Migr8.rb
Migr8.rb is a database schema version management tool.
- Easy to install, easy to setup, and easy to start
- No configuration file; instead, only two environment variables
- Designed carefully to suit Git or Mercurial
- Supports SQLite3, PostgreSQL, and MySQL
- Written in Ruby (>= 1.8)
Quick Start
-
Donwload migr8.rb.
$ curl -Lo migr8.rb http://bit.ly/migr8_rb
$ chmod a+x migr8.rb
### or
$ gem install migr8
-
Set environment variables: $MIGR8_COMMAND and $MIGR8_EDITOR.
$ export MIGR8_COMMAND="sqlite3 dbfile1" # for SQLite3
$ export MIGR8_COMMAND="psql -q -U user1 dbname1" # for PostgreSQL
$ export MIGR8_COMMAND="mysql -s -u user1 dbname1" # for MySQL
$ export MIGR8_EDITOR="open -a TextMate" # for TextMate (MacOSX)
$ export MIGR8_EDITOR="emacsclient" # for Emacs
$ export MIGR8_EDITOR="vim" # for Vim
-
Create managiment files and table.
$ ./migr8.rb init # create files in current directory,
# and create a table in DB.
-
Now you can manage DB schema versions.
$ ./migr8.rb # show current status
$ ./migr8.rb new -m "create 'users' table" # create a migration
# or ./migr8.rb new --table=users
$ ./migr8.rb # show status again
$ ./migr8.rb up # apply migration
$ ./migr8.rb # show status again
$ ./migr8.rb hist # list history
-
You may got confliction error when git rebase
or git pull
.
In this case, you must resolve it by hand.
(This is intended design.)
$ git rebase master # confliction!
$ ./migr8.rb hist -o # open 'migr8/history.txt', and
# resolve confliction manually
$ ./migr8.rb hist # check whether history file is valid
$ git add migr8/history.txt
$ git rebase --continue
Templating
(!!Attention!! this is experimental feature and may be changed in the future.)
It is possible to embed eRuby code into up
and down
scripts.
Syntax:
<% ... %>
: Ruby statement<%= ... %>
: Ruby expression, escaping '
into ''
(or \'
on MySQL)<%== ... %>
: Ruby expression, no escaping
For example:
vars:
- table: users
up: |
insert into ${table}(name) values
<% comma = " " %>
<% for name in ["Haruhi", "Mikuru", "Yuki"] %>
<%= comma %>('<%= name %>')
<% comma = ", " %>
<% end %>
;
down: |
<% for name in ["Haruhi", "Mikuru", "Yuki"] %>
delete from ${table} where name = '<%= name %>';
<% end %>
The above is the same as the following:
up: |
insert into users(name) values
('Haruhi')
, ('Mikuru')
, ('Yuki')
;
down: |
delete from users where name = 'Haruhi';
delete from users where name = 'Mikuru';
delete from users where name = 'Yuki';
In eRuby code, values in vars
are available as instance variables.
For example:
version: uhtu4853
desc: register members
author: kyon
vars:
- table: users
- members: [Haruhi, Mikuru, Yuki]
up: |
<% for member in @members %>
insert into ${table}(name) values ('<%= member %>');
<% end %>
down: |
<% for member in @members %>
delete from ${table} where name = '<%= member %>';
<% end %>
If you want to see up and down scripts rendered, run migr8.rb show
action.
For example:
$ ./migr8.rb show uhtu4853
version: uhtu4853
desc: register members
author: kyon
vars:
- table: "users"
- members: ["Haruhi", "Mikuru", "Yuki"]
up: |
insert into users(name) values ('Haruhi');
insert into users(name) values ('Mikuru');
insert into users(name) values ('Yuki');
down: |
delete from users where name = 'Haruhi';
delete from users where name = 'Mikuru';
delete from users where name = 'Yuki';
Notice that migration file using eRuby code is not compatible with other
Migr8 implemtation.
Tips
-
migr8.rb up -a
applys all migrations, while migr8.rb up
applys a
migration.
-
migr8.rb -D up
saves SQL executed into migr8/history.txt
file.
-
migr8.rb redo
is equivarent to migr8.rb down; migr8.rb up
.
-
migr8.rb new -p
generates migration file with plain skeleton, and
migr8.rb new --table=name
generates with table name.
-
migr8.rb unapply -x
unapplies migration which is applied in DB but
corresponding migration file doesn't exist.
(Describing in detail, migr8.rb unapply -x abcd1234
runs down
script
in _migr_history
table, while migr8.rb unapply abcd1234
runs down
script in migr8/migrations/abcd1234.yaml
file.)
This may help you when switching Git/Hg branch.
-
migr8.rb
generates sql file and run it with sql command such as psql
(PostgreSQL), sqlite3
(SQLite3) or mysql
(MySQL). Therefore you can
use non-sql command in migration file.
For example:
up: |
-- read data from CSV file and insert into DB (PostgreSQL)
\copy table1 from 'file1.csv' with csv;
-
MySQL doesn't support transactional DDL.
It will cause troubles when you have errors in migration script
(See https://www.google.com/search?q=transactional+DDL for details).
On the other hand, SQLite3 and PostgreSQL support transactional DDL,
and DDL will be rollbacked when error occurred in migration script.
Very good.
Usage and Actions
Usage: migr8.rb [global-options] [action [options] [...]]
-h, --help : show help
-v, --version : show version
-D, --debug : not remove sql file ('migr8/tmp.sql') for debug
Actions: (default: status)
readme : !!READ ME AT FIRST!!
help [action] : show help message of action, or list action names
init : create necessary files and a table
hist : list history of versions
-o : open history file with $MIGR8_EDITOR
-b : rebuild history file from migration files
new : create new migration file and open it by $MIGR8_EDITOR
-m text : description message (mandatory)
-u user : author name (default: current user)
-v version : specify version number instead of random string
-p : plain skeleton
-e editor : editr command (such as 'emacsclient', 'open', ...)
--table=table : skeleton to create table
--column=tbl.col : skeleton to add column
--index=tbl.col : skeleton to create index
--unique=tbl.col : skeleton to add unique constraint
show [version] : show migration file with expanding variables
-x : load values of migration from history table in DB
edit [version] : open migration file by $MIGR8_EDITOR
-r N : edit N-th file from latest version
-e editor : editr command (such as 'emacsclient', 'open', ...)
status : show status
up : apply next migration
-n N : apply N migrations
-a : apply all migrations
down : unapply current migration
-n N : unapply N migrations
--ALL : unapply all migrations
redo : do migration down, and up it again
-n N : redo N migrations
--ALL : redo all migrations
apply version ... : apply specified migrations
unapply version ... : unapply specified migrations
-x : unapply versions with down-script in DB, not in file
delete version ... : delete unapplied migration file
--Imsure : you must specify this option to delete migration
TODO
- [_] write more tests
- [_] test on windows
- [_] implement in Python
- [_] implement in JavaScript
Changes
Release 0.4.4 (2014-07-19)
- [bugfix] fix
redo
action to run down
first internally.
Release 0.4.3 (2014-02-28)
- [bugfix] fix reporting error when there is a migration which is
applied but migration file doesn't exist.
Release 0.4.2 (2014-02-05)
- [bugfix] re-packaging gem file
Release 0.4.1 (2014-02-05)
- [bugfix] Fix to allow migration file which contains no vars.
Release 0.4.0 (2013-11-28)
- [enhance] RubyGems package available.
You can install migr8.rb by
gem install migr8
. - [enhance] eRuby templating
up
and down
script.
See 'Templating' section of README file for details. - [enhance] Add new action 'show' which shows migration attributes
with expanding variables (ex:
${table}
) and renderting template. - [enhance] Add new action 'delete' which deletes unapplied migration file.
Note: this action can't delete migration which is already applied.
- [enhance] Add new option 'new -v version' in order to specify version
number by yourself instead of auto-generated random string.
- [bufix] Action 'edit version' now can open migration file even when
version number in migration file is wrong.
Release 0.3.1 (2013-11-24)
- [bugfix] Fix 'hist' action not to raise error.
Release 0.3.0 (2013-11-22)
- [enhance] Add
-x
option to unapply
action which unapplies migrations
by down-script in DB, not in migration file.
You can unapply migrations which files are missing in some reason. - [change] Eliminate indentation from output of 'readme' action.
Release 0.2.1 (2013-11-20)
- [bugfix] Fix
new --table=name
action to set table name correctly
Release 0.2.0 (2013-11-14)
- [enhance] Add new options to
new
action for some skeletons
new --table=table
: create tablenew --column=tbl.col
: add column to tablenew --index=tbl.col
: create index on columnnew --unique=tbl.col
: add unique constraint on column
- [enhance] Add new option
hist -b
action which re-generate history file. - [change] Change several error messages
- [change] Tweak SQL generated on SQLite3
Release 0.1.1 (2013-11-12)
- [IMPORTANT] Change history table schema: SORRY, YOU MUST RE-CREATE HISTORY TABLE.
- [enhance] Fix 'up' action to save both up and down script into history table.
Release 0.1.0 (2013-11-11)
License
$License: MIT License $
Copyright
$Copyright: copyright(c) 2013-2014 kuwata-lab.com all rights reserved $