I used to work with DBIx::Class::Schema::Versioned to upgrade my DBIC Schema but soon I needed more then it offered.

Starting with DBIx::Class::DeploymentHandler was a bit troublesome because I had a hard-ish time understanding the extensive documentation.

Now that I moved past that phase I want to present my way of using DeploymentHandler and hopefully spare you some of the burden.

Note: I write my DBIC schema resultclasses by hand and deploy to whatever database system I need.

Feature list * each schema version should be installable to a clean/empty database * single step upgrades of schema versions * create pl scripts that do something on the schema before and/or after upgrade

./script/database.pl usage: database.pl --cmd prepare [ --from-version $from --to-version $to ] database.pl --cmd install [ --version $version ] database.pl --cmd upgrade database.pl --cmd database-version database.pl --cmd schema-version

Simply create your DBIC schema and once you are ready add

our $VERSION = 1;

to Schema.pm

Run

database.pl --cmd prepare

this command creates the following files

db_upgrades/ ├── PostgreSQL │ └── deploy │ └── 1 │ ├── 001-auto.sql │ └── 001-auto-__VERSION.sql └── _source └── deploy └── 1 ├── 001-auto-__VERSION.yml └── 001-auto.yml

Run

database.pl --cmd install

to deploy the schema to your database

Next we change the schema. add a column to a table and increase the schema version to 2.

then run

database.pl --cmd prepare --from-version 1 --to-version 2

the deployment directory now look like this:

db_upgrades/ ├── PostgreSQL │ ├── deploy │ │ ├── 1 │ │ │ ├── 001-auto.sql │ │ │ └── 001-auto-__VERSION.sql │ │ └── 2 │ │ ├── 001-auto.sql │ │ └── 001-auto-__VERSION.sql │ └── upgrade │ └── 1-2 │ └── 001-auto.sql └── _source └── deploy ├── 1 │ ├── 001-auto-__VERSION.yml │ └── 001-auto.yml └── 2 ├── 001-auto-__VERSION.yml └── 001-auto.yml

Sometimes you want to do stuff with your schema before you change the DDL. With DBIx::Class::DeploymentHandler you can run SQL and or PL files before and after changing the DDL.

Since perl scripts are mostly independent of your choice of DBRMS it's best to put them in the special directory _common. Files from _common will be merged with the storage specific files So we have to make sure the file names reflect the order we want them exectuted in.

create directroy

mkdir -p db_upgrades/_common/upgrade/1-2/

create perl script

touch db_upgrades/_common/upgrade/1-2/001_do_stuff_BEFORE_ddl_change.pl

rename auto-generated sql file so the perl script is exectured before the DDL change

mv db_upgrades/PostgreSQL//upgrade/1-2/001-auto.sql db_upgrades/PostgreSQL//upgrade/1-2/002-auto.sql db_upgrades/ ├── _common │ └── upgrade │ └── 1-2 │ └── 001_do_stuff_BEFORE_ddl_change.pl ├── PostgreSQL │ ├── deploy │ │ ├── 1 │ │ │ ├── 002-auto.sql │ │ │ └── 001-auto-__VERSION.sql │ │ └── 2 │ │ ├── 001-auto.sql │ │ └── 001-auto-__VERSION.sql │ └── upgrade │ └── 1-2 │ └── 001-auto.sql └── _source └── deploy ├── 1 │ ├── 001-auto-__VERSION.yml │ └── 001-auto.yml └── 2 ├── 001-auto-__VERSION.yml └── 001-auto.yml

Here is an example script 001dostuffBEFOREddl_change.pl

#!/usr/bin/env perl use strict; use warnings; use DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator::ScriptHelpers 'schema_from_schema_loader'; schema_from_schema_loader( { naming => 'current' }, sub { my ( $schema, $versions ) = @_; # do stuff with $schema } );

and finally my database.pl file