CakePHP3のマイグレーションまとめ

More than 1 year has passed since last update.

CakePHP3のマイグレーションについて調べたので備忘録。(色んな記事の寄せ集めという感じ:sunglasses:)


概要


  • CakePHP3ではマイグレーションツール Phinx を採用している (Cakeのコマンドはラッパー)

  • コマンドが2種類ある (bin/cake migrationsbin/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からマイグレーションファイルを作成

https://book.cakephp.org/3.0/ja/migrations.html#id14


コマンド

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用アダプタを使用して書き直す必要あり?



    • インデックス, ユニークキー, 外部キーの名前が少し変わっている




マイグレーションファイルを作成

https://book.cakephp.org/3.0/ja/migrations.html#id3

作成方法は2通り。

作成方法によって、マイグレーションファイル冒頭のuse宣言が異なる (内部的にはほぼ同じっぽい)


パターン1 bin/cake bake migration マイグレーション名 で作成 (お手軽版)


シンタックス

bin/cake bake migration マイグレーション名 カラム定義

命名パターン
処理内容

(/^(Create)(.*)/)
指定したテーブルを作成

(/^(Drop)(.*)/)
指定したテーブルを削除

(/^(Add).(?:To)(.)/)
指定したテーブルにカラム追加

(/^(Remove).(?:From)(.)/)
指定のテーブルのカラムを削除

(/^(Alter)(.*)/)
指定したテーブルを変更 (CreateTable と AddFieldの別名)


例) テーブル作成


コマンド

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 を参考に処理を書く
}
}


マイグレーションファイルのメソッドについて

以下のメソッドが使用可能

 

※ change()指定時は、up()やdown()を書いても無視される

※ なので、change()のみを書いたファイルか、up()/down()を書いたファイルを作成する


Phinxで利用可能なフィールドの型

https://book.cakephp.org/3.0/ja/migrations.html#id8


  • string

  • text

  • integer

  • biginteger

  • float

  • decimal

  • datetime

  • timestamp

  • time

  • date

  • binary

  • boolean

  • uuid

RDBMS固有の型、MySQLのtinyint等を指定したい場合、以下のアダプタを使用する


マイグレーション実行

https://book.cakephp.org/3.0/ja/migrations.html#migrate


最新まで実行


コマンド

bin/cake migrations migrate



指定したマイグレーションIDまで実行


コマンド

bin/cake migrations migrate -t マイグレーションID



ロールバック

https://book.cakephp.org/3.0/ja/migrations.html#rollback


1つ前に戻す


コマンド

bin/cake migrations rollback



指定したマイグレーションIDまで戻す


コマンド

bin/cake migrations rollback -t マイグレーションID



マイグレーションを実行済みにする(DBには反映しない)

https://book.cakephp.org/3.0/ja/migrations.html#mark-migrated


すべて実行済みにする


コマンド

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 |
+----------------+----------------+---------------------+---------------------+------------+


差分算出用ダンプファイルのみ作成

https://book.cakephp.org/3.0/ja/migrations.html#dump-bake


コマンド

bin/cake migrations dump



  • config/Migrations/schema-dump-default.lock がファイルが作成(更新)される

  • その時点のDB情報が保存されている

  • ダンプファイルは、migrate / rollback / スナップショット実行時にも作成される

  • このコマンドで作成したダンプファイルでは、うまく差分算出できなかった


現在のDB状態とダンプファイルの差分からマイグレーションファイルを作成

https://book.cakephp.org/3.0/ja/migrations.html#id15


コマンド

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 がファイルが作成(更新)される


初期データの作成

https://book.cakephp.org/3.0/ja/migrations.html#seed

Phinxのseed機能により初期データ用ファイルを作成できる。

あとで追記予定。