Monorail - Database Migrations
version 0.4
startup-monorail
./monorail.pl make_migration
./monorail.pl migrate
This module attempts to provide a simplier and more robust way to manage database migrations with DBIx::Class. This library borrows (steals!) ideas heavily from django's migrations.
The main goals of this library are to free the programmer from keeping track of schema versions and to work well with projects that have many branches in play.
Tables, their fields, views, triggers and procedures are all defined via the result classes in DBIx::Class. Whenever possible, Monorail does not add any functionality to DBIx::Class, but instead depends on existing deployment hooks.
Any tool like Monorail ends up building a set of database updates called migrations. In other tools like DBIx::Class::DeploymentHandler these changes are SQL files, with monorail these migrations are objects.
See Monorail::Role::Migration for an example of what these migration files look like.
You do not need an active database connection to build a migration. Monorail compares the DBIx::Class schema on disk to a sql translator schema that contains all the changes defined in the migrations. This is where having the changes defined in perl becomes powerful - the objects in each migration know how to express themselves as SQL or as a change to a SQL::Translator schema).
Each migration has a list of other migrations that it depends on. This is used to build a tree (a directed acyclic graph if you want to be fancy) that describes the relationships between the migrations. Any new migration will be created with the sink vertices as its dependencies. This means that new migrations depend on all the previous migrations.
It's also worth noting that all migrations in the monorail directory are included in the dependency tree. When a database is updated the tree is walked in topological order.
Pretty much every migration system I've looked at keeps track of what version a database is at. Usually this is a table with a integer column and a single row. There's migrations 1 thru 9 and the database is at 7? Apply 8 and 9.
Monorail inserts a row with the migration name when it is applied, then as we are walking the tree we can just skip migrations that have the row.
The DBIx::Class::Schema object for the schema we're managing. This will be used to inspect the current state of the result classes and for the DBI handle to the database we're updating.
Required.
A string representing the type of database we're connecting to. By default this is dirived from the connection within dbix
.
The directory where our migration files live. Required.
The recorder object is responsible for the table that stores migration states as discussed above.
A Monorail::MigrationScript::Set object representing all the migrations that currently exist in the basedir.
A Monorail::Diff object representing the current difference between the DBIx::Class schema on disk and the sum of the current migrations.
A boolean flag. When true this module will print no informative messages to STDOUT
. Defaults to false.
$monorail->make_migration();
# or
$monorail->make_migration('add_visitor_table');
Compares the current DBIx::Class definitions on disk to a ProtoDBIX built from all the migrations. If there are differences, a new migration script will be created that contains those differences. If no name is passed an autogenerated unique name will be used - otherwise the given name is used.
$monorail->migrate
Updates the database that we're connected to the current state of the migrations. Walks the dependency tree in topological order, applying all migrations that are not yet applied.
Prints all the migrations by name in order. If the migration has been applied to the database, it will be marked with [X]
in the output.
Prints all the migration that would be applied by migrate()
.
Prints a SQL representation of the given migration names.
This word is basically a perl port of django migrations. Many many thanks in that direction.
Anyone that worked on SQL::Translator, that module is a nuclear powered sonic swiss army knife of handy. This module is mostly just sugar on top of it.
The DBIx::Class authors and contributers deserve a lot of free drinks for building a great ORM.
Chris Reinhardt [email protected]
This software is copyright (c) 2015 by Liquid Web Inc.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.