読者です 読者をやめる 読者になる 読者になる

PerlerのRuby日記

Rubyとか

Sequelの2つのマイグレーションファイル命名規則

http://sequel.jeremyevans.net/rdoc/files/doc/migration_rdoc.html

Sequelのマイグレーションファイルは2つの命名規則から選ぶことができる。
インクリメンタルな数字をつける方法と、タイムスタンプをつける方法の2つ。

両方とも管理するデータベース内に、スキーマ情報を格納するテーブルが追加される。

インクリメント方式(IntegerMigrator)

001_create_artists.rb
002_add_artist_location.rb

ファイル名の頭に数字をつける方法。

見た目上の理由から0パディングして3桁くらいにしておくと綺麗に見える。
(見た目だけの問題なので、別に強制ではない)

スキーマ情報として"schema_info"テーブルが作成され、フィールド"version"の中に実行したマイグレーションファイルのバージョン番号が入る。これは常に1行で、マイグレーションされるたびにUPDATEされる。

タイムスタンプ方式(TimestampMigrator)

# Date
20100510_create_artists.rb
# Date and Time
20100510120000_create_artists.rb

# Unix Epoch Time Integer
1273518000_create_artists.rb

ファイル名の頭にタイムスタンプをつける方法。ActiveRecordっぽい。
タイムスタンプというものの「20000101」を超える数字であれば、「YYYYMMDD」でもUnix time(1384855279のような)でも問題ない。

逆にいえば「20000101」よりも小さい数字はIntegerMigratorとして使われる。

ちなみに「20000101_create_table.rb」だと

Error: Sequel::Migrator::Error: Migration number too large, must use TimestampMigrator

というようなエラーが出る。

スキーマ情報として"schema_migrations"テーブルが作成され、フィールド"filename"の中に実行したマイグレーションファイルのファイル名が入る。これはマイグレーションされるたびにINSERTされる。


どちらを使うべきか

公式でIntegerMigratorを推している。
マイグレーション実行時の挙動に違いがあって、TimestampMigratorの方がリスクが高いことを理由にしている。

IntegerMigratorの場合、同じ番号のファイル名を作ると(34_do_this.rbと34_do_that.rbのように)いざマイグレーションを実行するときに

Duplicate migration version

エラーとなり、直列性を守ることができる。
複数人での開発に非常に有効な手段となることが容易に想像できる。
(早い者勝ち勝負に負けると、ファイル名のrenameコミットを積むかrebaseの必要が生じる)


これがTimestampMigratorだと、同じタイムスタンプであってもファイル名後半部分が異なればマイグレーション実行できる
(20100512_do_this.rbと20100512_do_that.rbのように)
さらにタイムスタンプ自体がDBに反映されているものより小さくしても、実行可能である
単純に"schema_migrations"テーブルに存在しないファイル名を見つけ出して実行しているだけのようだ。
これでは直列性がなくなり、実際にDBに充てる順番があとあと分からなくなってしまう。



ゆえに、新規でSequelのマイグレーション機能を使うなら、IntegerMigratorで管理するのがよい。