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)
-
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
orgit 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
(!!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.
-
migr8.rb up -a
applys all migrations, whilemigr8.rb up
applys a migration. -
migr8.rb -D up
saves SQL executed intomigr8/history.txt
file. -
migr8.rb redo
is equivarent tomigr8.rb down; migr8.rb up
. -
migr8.rb new -p
generates migration file with plain skeleton, andmigr8.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
runsdown
script in_migr_history
table, whilemigr8.rb unapply abcd1234
runsdown
script inmigr8/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 aspsql
(PostgreSQL),sqlite3
(SQLite3) ormysql
(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: 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
- [_] write more tests
- [_] test on windows
- [_] implement in Python
- [_] implement in JavaScript
- [bugfix] fix reporting error when there is a migration which is applied but migration file doesn't exist.
- [bugfix] re-packaging gem file
- [bugfix] Fix to allow migration file which contains no vars.
- [enhance] RubyGems package available.
You can install migr8.rb by
gem install migr8
. - [enhance] eRuby templating
up
anddown
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.
- [bugfix] Fix 'hist' action not to raise error.
- [enhance] Add
-x
option tounapply
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.
- [bugfix] Fix
new --table=name
action to set table name correctly
- [enhance] Add new options to
new
action for some skeletonsnew --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
- [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.
- Public release