CakePHP3/Migrations

投稿者: | 2018-03-13

概要

例によってメモ。既出であっても自分に必要な情報を一画面(一ドキュメント)にまとめて置いたり、リンク集を作っておくというのはいい手段です。バイト先で扱うことになりましたが現場の誰もcakephp3のmigrationsを知らないらしいので私が調べてまとめることになりました。その一日の成果です。

参考リンク集

cookbook – Migrations
Qiita – CakePHP3のマイグレーションまとめ
Qiita – CakePHP Migrations の limit オプションについて 

他、必要に応じてリンクをはります。

Install

$ composer require cakephp/migrations "@stable"

して、config/bootstrap.phpに以下を追加

既存DBからマイグレーション生成(スナップショット)

$ bin/cake bake migration_snapshot Initial

Initial部分はマイグレーションファイルのIDになるので好きな名前を指定できる。名前はユニークっぽい。生成したマイグレーションのステータスは適応済み(up)になる。

MigrationファイルからMigration実施

新規Migrationファイルを取得した場合もこのコマンドを実施
※初回の場合は、DBを空にしておかないとコケるので注意(既に同じ名前のテーブルがあるときcreate()メソッドが通らない)

$ bin/cake migrations migrate

既知の問題

スナップショットを作っただけでは現状のDBを再現することはできない。CakePHPのMigrationが扱える型に反するらしい。例えば、生成したマイグレーションの中に、以下のようなtinyintの指定があるが

このマイグレーションは適応できない。以下のエラー(抜粋)が出る。

Error: [InvalidArgumentException] An invalid column type "tinyinteger" was specified for column "hoge_flag".

つまり、そのまま引っこ抜いただけでは使えず、手での修正が必要となる。PhinxのWriting Migrationsによれば、型を’integer’に修正した上で、’limit’ => MysqlAdapter::INT_TINYと指定してやる必要があるらしい。以下書き方の抜粋。

また、double型はfloat型に直されて出力される。floatを許容するか、decimalに置換して対応するか。

decimalを指定した時に使えるoption、precisionとscaleがある。上記の例でマイグレートすると、tekitou_valというカラムの型はdecimal(12,3)になる。

コマンド

以下参照。

Migrations コマンド

seed生成

参考:seed : データベースの初期データ投入

実データを元にseedを生成するにはdataオプションを使う

$ bin/cake bake seed --data テーブル名

データ数の上限もlimitオプションで決められる。

$ bin/cake bake seed --data --limit 10 テーブル名

seedを適応するには以下のコマンド

$ bin/cake migrations seed

マイグレーションファイルのステータスについて

マイグレーションが適応済みかどうか見るには

$ bin/cake migrations status

で確認する。以下結果例。

upは適応済み、downは適応していない。migrations migrateするとdownのものが適応される。また、適応したマイグレーションファイルはphinxLogテーブル(勝手に作られる管理用テーブル)で管理される。このテーブルが保持するレコードを消すことで無理やりdown状態にすることもできる。通常はmigrations rollbackコマンドで差戻す。

マイグレーションファイルが持つメソッド

up(),down(),change()がある。

up()はマイグレーションファイルを適応するときに走り、down()はロールバックする時に走る。したがって、up()とdown()では逆の処理を書くようにしてやれば良い。

change()はup,down時両方走る。change()に記述する内容はup時の処理で、downしたときはそれぞれの処理に対応する逆処理が走る(change内でaddColumn()していたとすると、ロールバック時にはその処理がremoveColumn()に読み替えられる)。ただし、逆処理にできない命令もあるので取り扱いには注意が必要。また、change()が定義されている場合up(),down()は走らない。

change()についての参考

対応表抜粋

changeメソッド内のコマンド(migrateで実行) rollbackで実行されるコマンド
createTable dropTable
renameTable renameTable(引数逆)
addColumn removeColumn
renameColumn renameColumn(引数逆)
addIndex removeIndex
addForeignKey dropForeignKey