CakePHP3では、DBスキーマの更新管理にPhinxを使ったMigrationsというプラグインを使います。(Migrationsはデフォルトで入っています。)
使い方をざっくり説明します。
既存のテーブルからマイグレーションファイルを作る
1から書いてもいいのですがけっこう大変なので、最初はテーブルを作成してからマイグレーションファイルをbakeするのが簡単です。
bin/cake bake migration_snapshot Initial
app/config/Migrations/20151204000000_initial.php
のようなマイグレーションファイルができます。
コマンド操作
app/config/Migrations/
以下に作成したマイグレーションファイルを元にDBに適用します。
適用
未適用のファイルを適用します。
bin/cake migrations migrate
ロールバック
適用したものを戻します。
bin/cake migrations rollback
適用状況を確認
どれが適用済みでどれが未適用かなどのステータスを確認できます。
bin/cake migrations status
↓こんな感じのものが出力されます。
Status Migration ID Migration Name
-----------------------------------------
up 20150522085101 Initial
up 20150526022603 RenameColumn
down 20150527003127 AddPriceToProducts
upが適用済みでdownが未適用です。
マイグレーションファイル
bakeしてできたファイルを見たらなんとなくわかると思いますが、up()
、down()
、change()
というメソッドの中に、追加・削除・変更の定義を書きます。
up()
に適用したいもの(migrateで実行したいもの)を書き、down()
にはup()
に書いたものをロールバックする時に実行するべきものを書きます。
例えば、up()
にcreate tableを書いたら、down()
にdrop tableを書きます。
class Initial extends AbstractMigration
{
public function up()
{
$table = $this->table('users');
$table
->addColumn('name', 'string', [
'default' => null,
'limit' => 50,
'null' => false,
])
->addColumn('profile', 'text', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('created', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('modified', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->create();
}
public function down()
{
$this->dropTable('users');
}
}
change()
もup()
と同じように適用したいものを書きますが、change()
に書くと、down()
は自動的に推測してくれます。
なので、自動的に推測できるものしかchange()
には書けません。
例えばaddColumnは自動的にremoveColumnが推測できるので書けますが、removeColumnはaddColumnが推測できない(カラムの定義がわからない)ので書けません。(書けなくはないけど、ロールバックできなくなるんだと思います。)
また、save()
は使えず、create()
とupdate()
を使う必要があります。
class AddBirthdayToUsers extends AbstractMigration
{
public function change()
$table = $this->table('users');
$table
->addColumn('birthday', 'date', [
'default' => null,
'limit' => null,
'null' => true,
])
->update();
}
}
class RemoveProfileFromUsers extends AbstractMigration
{
public function change()
{
$table = $this->table('users');
$table->removeColumn('profile');
$table->update();
}
}
また、change()
を書くとup()
とdown()
は無視されるので、change()
だけのファイルかup()
とdown()
のファイルかのどちらかにする必要があります。
マイグレーションファイル書くのはちょっとめんどうな気もしますが、bakeでも作成できますし、バージョン管理できるのと、開発で変更したものを本番に適用する時も楽にできます。
さらに詳細は、
Cookbook 3.x - Migrations (いつのまにか翻訳されてる!)
と
Phinx - Writing Migrations
を見てください。