C Sharpens you up

http://qiita.com/yuba に移しつつあります

Play! framework Evolutionsのsqlファイルの優先順位

Play! frameworkではEvolutionsファイルを書くことでデータベースへのスキーマ適用とか更新がWebからワンタッチできるようになります。ありがたいですね。

sqlスクリプトファイルがスキーマ変更1件を表していて、【変更を適用するSQL文(Ups)】【変更を取り消すSQL文(Downs)】の組み合わせで記述されます。

さてその公式ドキュメントを読んでみると気になる記述が。

最初のスクリプトは 1.sql、2番目のスクリプトは 2.sql、…というように名前をつけます。

http://www.playframework-ja.org/documentation/2.0.4/Evolutions

2番目のスクリプトってどういう意味だ。
いやスクリプト1本がスキーマ変更1件を表すんだから、スクリプトが複数あるのはわかる。この何番目という順位に意味はあるのかってことです。ドキュメントに書いていない。

実験してみました。
スクリプトファイル4本を用意してevolutions/defaultディレクトリに配置します。

1.sql
2.sql
3.sql
5.sql

内容は適当。どのファイルを変更するとどのSQLが呼び出されるかが問題。

  • 初回実行 ⇒ 1.sql Ups, 2.sql Ups, 3.sql Ups の順で実行されます。5.sqlは実行されません。1から連番で続いているスクリプトファイルだけが認識されたよう。
  • 3.sqlを編集する ⇒ 3.sql Downs, 3.sql Ups の順で実行されます。順当に適用されました。
  • 2.sqlを編集する ⇒ 何も起こりません。一番大きな数字のスクリプト以外は編集しても適用されないのです。一番大きな数字のスクリプト(ここでは3.sql)のことをトップと呼ぶことにしましょう。
  • 2.sqlに編集が入った状態で3.sqlを編集する ⇒ 3.sql Downs, 2.sql Downs, 2.sql Ups, 3.sql Ups の順で実行されます。トップが編集された場合は、下位のスクリプトも順当に適用されるわけです。適用順を見ると、若い数字のものは大きい数字のものの前提になっている変更という位置づけですね。
  • 1.sqlに編集が入った状態で3.sqlを編集する ⇒ 3.sql Downs, 3.sql Ups の順で実行されます。1.sqlの編集は無視されてしまいました。トップのすぐ前のスクリプトしかトップの適用に付き合ってくれないんですね。
  • 1.sql, 2.sqlに編集が入った状態で3.sqlを編集する ⇒ 3.sql Downs, 2.sql Downs, 1.sql Downs, 1.sql Ups, 2.sql Ups, 3.sql Ups の順で実行されます。待望の全部盛り実行です。

これで結論が出ました。

  1. 1.sqlから連続する数のスクリプトファイルが認識される
  2. 認識した中で最大の番号のスクリプトに変更があれば、Downs, Upsが実行される。
  3. スクリプトのDowns, Upsを実行するとき、一つ前のスクリプトにも変更があれば、Downs, Upsの間に割り込む形で一つ前のスクリプトのDowns, Upsが実行される。

若いスクリプトは続くスクリプトの前提になっているスキーマ変更だという位置づけからすれば、どのスクリプトの変更があったときにも必ずそこまで掘り込んで実行、というのが正しい動作だと思うんですけどね。こういう仕様になっておられました。