CakePHP3のマイグレーションについて調べたので備忘録。(色んな記事の寄せ集めという感じ)
- 2017-05-25時点の情報
- 検証環境
- CakePHP3 : Ver. 3.4.6
- MariaDB : Ver. 10.1.23
- 参考ドキュメント
- https://book.cakephp.org/3.0/ja/migrations.html
- http://docs.phinx.org/en/latest/migrations.html
- QiitaのCakePHP3マイグレーション関連記事
概要
- CakePHP3ではマイグレーションツール Phinx を採用している (Cakeのコマンドはラッパー)
- コマンドが2種類ある (bin/cake migrations と bin/cake bake migration)
- /bin/cake コマンドは php /bin/cake.php でもOK
- マイグレーションファイルは config/Migration/ 以下に作成される
- ファイル名は、作成日時(YYYYMMDDHHMMSS)_マイグレーション名.php
- 明示的にオプション指定しない限り、defaultのデータベース設定を使用する
- migrationコマンドを実行すると、データベースにphinxlogテーブルを作成し、このテーブルで実行履歴を管理する
MariaDB > select * from phinxlog;
+----------------+----------------+---------------------+---------------------+------------+
| version | migration_name | start_time | end_time | breakpoint |
+----------------+----------------+---------------------+---------------------+------------+
| 20170525090543 | Initial | 2017-05-25 09:05:43 | 2017-05-25 09:05:43 | 0 |
| 20170525090709 | CreateProducts | 2017-05-25 09:27:41 | 2017-05-25 09:27:41 | 0 |
+----------------+----------------+---------------------+---------------------+------------+
マイグレーション適用状況を確認
コマンド
bin/cake migrations status
↓結果はこんな感じ
結果
Status Migration ID Migration Name
-----------------------------------------
up 20170525090543 Initial
down 20170525090709 CreateProducts
- up = 実行済み
- down = 未実行
現在のDBからマイグレーションファイルを作成
コマンド
bin/cake bake migration_snapshot Initial
- config/Migration/YYYYMMDDHHMMSS_Initial.php がファイルが作成される
- config/Migrations/schema-dump-default.lock がファイルが作成(更新)される
- スキーマのみで、データ部分は作成されない (データはseed機能で入れる)
- Initialはマイグレーション名なので他の名前でもOK
- migrations statusは実行済みになる
- 作成したファイルをmigrationコマンドでリストアしても同じ定義には戻らなかった(MySQL/MariaDBの場合)
- tinyint(x)が、int(x)に変わっている
- tinyint(1)の場合、恐らくCakePHP内部で、booleanをtinyint(1)として扱っているのでint(x)にならない
- tinyintを指定したい場合、MySQL用アダプタを使用して書き直す必要あり?
- インデックス, ユニークキー, 外部キーの名前が少し変わっている
- tinyint(x)が、int(x)に変わっている
マイグレーションファイルを作成
作成方法は2通り。
作成方法によって、マイグレーションファイル冒頭のuse宣言が異なる (内部的にはほぼ同じっぽい)
パターン1 bin/cake bake migration マイグレーション名
で作成 (お手軽版)
シンタックス
bin/cake bake migration マイグレーション名 カラム定義
- マイグレーション名
- https://book.cakephp.org/3.0/ja/migrations.html#id6
- マイグレーション名の命名パターンによって作成される処理内容が変わる
命名パターン | 処理内容 |
---|---|
(/^(Create)(.*)/) | 指定したテーブルを作成 |
(/^(Drop)(.*)/) | 指定したテーブルを削除 |
(/^(Add).(?:To)(.)/) | 指定したテーブルにカラム追加 |
(/^(Remove).(?:From)(.)/) | 指定のテーブルのカラムを削除 |
(/^(Alter)(.*)/) | 指定したテーブルを変更 (CreateTable と AddFieldの別名) |
- カラム定義
- https://book.cakephp.org/3.0/ja/migrations.html#id8
- 以下のパターンで指定可能
- fieldName:fieldType?[length]:indexType:indexName
例) テーブル作成
コマンド
bin/cake bake migration CreateProducts name:string description:text created modified
- config/Migration/YYYYMMDDHHMMSS_CreateProducts.php が作成される
- change()メソッド内にaddColumn()とcreate()が記述されている
<?php
use Migrations\AbstractMigration;
class CreateProducts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('description', 'text', [
'default' => null,
'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('modified', 'datetime', [
'default' => null,
'null' => false,
]);
$table->create();
}
}
例) カラム追加
コマンド
bin/cake bake migration AddPriceToProducts price:decimal
- config/Migration/YYYYMMDDHHMMSS_AddPriceToProducts.php が作成される
- change()メソッド内にaddColumn()とupdate()が記述されている
<?php
use Migrations\AbstractMigration;
class AddPriceToProducts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->addColumn('price', 'decimal', [
'default' => null,
'null' => false,
]);
$table->update();
}
}
例) カラム削除
コマンド
bin/cake bake migration RemovePriceFromProducts price
- config/Migration/YYYYMMDDHHMMSS_RemovePriceFromProducts.php が作成される
- change()メソッド内にremoveColumn()とupdate()が記述されている
<?php
use Migrations\AbstractMigration;
class RemovePriceFromProducts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->removeColumn('price');
$table->update();
}
}
例) テーブル削除
コマンド
bin/cake bake migration DropProducts
- config/Migration/YYYYMMDDHHMMSS_DropProducts.php が作成される
- change()メソッド内にdrop()が記述されている
<?php
use Migrations\AbstractMigration;
class DropProducts extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->drop();
}
}
パターン2 bin/cake migrations create マイグレーション名
で作成 (カスタム定義用)
例)
コマンド
bin/cake migrations create CreateProducts
- config/Migration/YYYYMMDDHHMMSS_create_products.php が作成される
- 何も処理が記述されていないので、1から処理を記述する
- 引数のマイグレーション名はキャメルケースにしないとエラーになる
<?php
use Phinx\Migration\AbstractMigration;
class CreateProducts extends AbstractMigration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
// https://book.cakephp.org/3.0/ja/migrations.html や
// http://docs.phinx.org/en/latest/migrations.html を参考に処理を書く
}
}
マイグレーションファイルのメソッドについて
以下のメソッドが使用可能
-
up()
- http://docs.phinx.org/en/latest/migrations.html#the-up-method
-
migrations migrate
時に実行する処理を書く
-
down()
- http://docs.phinx.org/en/latest/migrations.html#the-down-method
-
migrations rollback
時に実行する処理を書く
-
change()
- http://docs.phinx.org/en/latest/migrations.html#the-change-method
- up()と同様にmigrate時に実行する処理を書いておくと、down()を自動的に推測してくれる
- 自動的に推測できる以下のコマンドしか書けない
- createTable
- renameTable
- addColumn
- renameColumn
- addIndex
- addForeignKey
- dropTableやremoveColumn等は、戻すべき元の定義が推測できないのでNG。up()/down()に書く
- 自動的に推測できる以下のコマンドしか書けない
- change()だけで、
migrations migrate
とmigrations rollback
両方いける - change()内ではcreate()かupdate()で追加・更新を行う。save()は使えない。drop()は使えるみたい
※ change()指定時は、up()やdown()を書いても無視される
※ なので、change()のみを書いたファイルか、up()/down()を書いたファイルを作成する
Phinxで利用可能なフィールドの型
- string
- text
- integer
- biginteger
- float
- decimal
- datetime
- timestamp
- time
- date
- binary
- boolean
- uuid
RDBMS固有の型、MySQLのtinyint等を指定したい場合、以下のアダプタを使用する
- MySQL用
- PostgreSQL用
マイグレーション実行
最新まで実行
コマンド
bin/cake migrations migrate
指定したマイグレーションIDまで実行
コマンド
bin/cake migrations migrate -t マイグレーションID
ロールバック
1つ前に戻す
コマンド
bin/cake migrations rollback
指定したマイグレーションIDまで戻す
コマンド
bin/cake migrations rollback -t マイグレーションID
マイグレーションを実行済みにする(DBには反映しない)
すべて実行済みにする
コマンド
bin/cake migrations mark_migrated
指定したマイグレーションIDだけマイグレーション済みにする
コマンド
bin/cake migrations mark_migrated --target=マイグレーションID --only
直接DBの方を変更済みの時などで、マイグレーションを実行したくない場合に、実行済みに出来る。
実行前
migrations status
Status Migration ID Migration Name
-----------------------------------------
up 20170525090543 Initial
down 20170525090709 CreateProducts
phinxlogテーブル
MariaDB > select * from phinxlog;
+----------------+----------------+---------------------+---------------------+------------+
| version | migration_name | start_time | end_time | breakpoint |
+----------------+----------------+---------------------+---------------------+------------+
| 20170525090543 | Initial | 2017-05-25 09:05:43 | 2017-05-25 09:05:43 | 0 |
+----------------+----------------+---------------------+---------------------+------------+
という状況で、コマンドを実行すると
コマンド
bin/cake migrations mark_migrated
以下のようになる (productsテーブルは作成されていない)
実行後
migrations status
Status Migration ID Migration Name
-----------------------------------------
up 20170525090543 Initial
up 20170525090709 CreateProducts
phinxlogテーブル
MariaDB > select * from phinxlog;
+----------------+----------------+---------------------+---------------------+------------+
| version | migration_name | start_time | end_time | breakpoint |
+----------------+----------------+---------------------+---------------------+------------+
| 20170525090543 | Initial | 2017-05-25 09:05:43 | 2017-05-25 09:05:43 | 0 |
| 20170525090709 | CreateProducts | 2017-05-25 09:27:41 | 2017-05-25 09:27:41 | 0 |
+----------------+----------------+---------------------+---------------------+------------+
差分算出用ダンプファイルのみ作成
コマンド
bin/cake migrations dump
- config/Migrations/schema-dump-default.lock がファイルが作成(更新)される
- その時点のDB情報が保存されている
- ダンプファイルは、migrate / rollback / スナップショット実行時にも作成される
- このコマンドで作成したダンプファイルでは、うまく差分算出できなかった
現在のDB状態とダンプファイルの差分からマイグレーションファイルを作成
コマンド
bin/cake bake migration_diff NameOfTheMigrations
- config/Migration/YYYYMMDDHHMMSS_NameOfTheMigrations.php が作成される
- 前回のダンプファイル(schema-dump-default.lock)更新以降に追加・削除されたスキーマのマイグレーション処理が書かれている
migrations dump
で作成したダンプファイルでは、差分がうまく出力されなかった(全スキーマのcreate文が出力された)-
migration_snapshot
/migrations migrate
で作成したダンプファイルでは問題なく差分のみ出力された
- config/Migrations/schema-dump-default.lock がファイルが作成(更新)される
初期データの作成
Phinxのseed機能により初期データ用ファイルを作成できる。
あとで追記予定。