Migration

最近Railsで開発していて、migrationを使い初めてみた。 (以前Rails使っていた頃は無かった気がする・・・) 激しく便利。軽くメモ代わりに。 データベースの定義(DDL)をRails側で実装出来る機能ですが何が嬉しいかといえば、
  • DDLをバージョン管理できる
  • いつでも任意のバージョンに戻す事ができる
  • modelさえ作ってしまえばテストデータをrubyで書いてinsertできる
チーム開発にはもってこいの機能です。

使い方

生成はscript/generateで。 ありがちなusersというテーブルを生成。
$ ruby script/generate migrate  create_users
こうすると、”001_create_users.rb”というファイルがdb/migrateに出来ているので、 テキストエディタで定義を編集。 self.upとself.downというメソッドがあるので、 self.upはバージョンアップ時に実行され、 self.downはダウングレード時に実行されるのね。
class CreateUsers < ActiveRecord::Migration
  def self.up
      options = {
        :options     => "ENGINE=innodb DEFAULT CHARSET=utf8"
      }
      create_table(:users, options) {|table|
        table.column :name,                 :integer
        table.column :password,             :string, limt => 50
        table.column :birth,                :date
        table.column :roll,                 :integer
        table.column :time_stamp,           :datetime
      }
  end
  def self.down
    drop_table : users 
  end
end
基本的にupにテーブル定義、 downにdrop_tableしておけばよい。 実際に動かしてみる。
$ rake migrate
これで、DBにusersテーブルが出来ているハズ。 逆にダウングレードする場合は
$ rake migrate VERSION=[バージョン番号]
としてあげればOK。 バージョンってのは、generateしたときに振られる "001"とかの連番。

スキーマ命令

スキーマ定義に使える命令をメモ代わりに
  • create_table(name, options) テーブルを作成する。
  • drop_table(name) テーブルを削除する。
  • add_column(table_name, column_name, type, options) カラムを追加する。
  • rename_column(table_name, column_name, new_column_name) カラム名の変更
  • change_column(table_name, column_name, type, options) カラム属性の変更
  • remove_column(table_name, column_name) カラムの削除
  • add_index(table_name, column_name): インデックスを追加する。
  • remove_index(table_name, column_name): インデックスを削除する。

定義に使える型

今のところ、PostgreSQLとMySQLのみ対応らしい。
抽象表現rubyでの型PostgreSQLMySQL
:primary_keyFixnumserial primary keyint(11) DEFAULT NULL auto_increment PRIMARY KEY
:stringStringcharacter varying(255)varchar(255)
:textStringtexttext
:integerFixnumintegerint(11)
:floatFloatfloatfloat
:datetimeTimetimestampdatetime
:timestampTimetimestampdatetime
:timeTimetimestampdatetime
:dateDatedatedate
:binaryStringbyteablob
:booleanObjectbooleantinyint(1)
ActiveRecord上でrubyでの型とDBの型で不具合が起こるとすれば、 decimal型のマッピングがFloatクラスにされる事で、演算を繰り返すと丸め誤差が生じる事。 migrationを使っていればその心配はない。 今日はこの辺りまで。