テーブル定義を直接変更した後にmigration_diffコマンドを使うと差分を認識してMigrationファイルを自動生成してくれる便利な機能があります。
./bin/cake bake migration_diff (設定名)
ですが、使い方を間違うとちょっと面倒なことが発生して、差分を自動生成してくれず、中身が空のマイグレーションファイルができてしまいます。
これの原因と対策を解説します。
原因
この現象が発生する原因は、テーブル定義を変更した後に migrations migrateコマンドをしてしまったことが原因です。
CakeのMigrationの仕組みとしては
migrateコマンドを実行すると、migrationファイルを日付順に処理して、適用していないマイグレーションファイルが見つかったらそれを実行します。
最後に、データベースのテーブルの状態をconfig/schema-dump-default.lockに現在のテーブルの状態を保存します。
migration_diffコマンドを実行するとlockファイルと現在のDBの状態のをみて、差分があればそれを出力するという仕組みになっています。
何ですが、このlockファイルの生成ロジックが曲者で、じつはMigrationファイルの内容と関係なくDBのテーブルの内容を保存してしまいます。
ですので、テーブル定義を変更した後に、誤って先にmigrateコマンドを実行してしまうと、変更した変更した内容も含んでlockファイルを上書き生成してしまいますので、その後にmigration_diffコマンドを実行しても、差分なしと判定されてしまうのです。
マイグレーションファイルになっていれば前の状態に戻すのは簡単ですが、lockファイルは、ファイル管理ソフトなどで差分管理をしていないと元に戻せないので非常に面倒です。
ということで、これを何とかする方法を解説します。
解決方法
まず、migration_diffでできてしまった空の設定を元に戻しておきましょう。
rollbackコマンドでmigration_diff発行前の状態に戻すことが可能です。
bin/cake migrations rollback -t 20150103081132<-タイムスタンプで特定の状態に戻せます
もしくは、生成されたmigrationファイルが空であれば、履歴を削除するだけでもOKです。
データベースにphinxlogというテーブルで管理しています。
これの最新のレコードを削除すればOKです。
次に、適当なデータベースを新規作成し、cakephpのDB接続先をそのデータベースに設定します。
そこで、一度migrations migrateコマンドを実行します。
これでMigrationファイルの内容でschema-dump-default.lockファイルが生成されます。
CakePHPのDB接続先情報を元に戻して、migration_diffコマンドを実行すればOKです。
./bin/cake bake migration_diff (設定名)
たまーにやっちゃうんですよねこのミス。どうやって直すんだっけとたまに忘れちゃうので記事にしてみました。
そもそもmigrations migrateコマンドで何の変更もないのに上書きしちゃうのがどうかと思う。Migrationファイルに追加がないのに現在のDBの内容と違う場合は、上書きしてもいいですか?ぐらい聞く配慮はしてほしいと思う。