16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHP 3Advent Calendar 2015

Day 4

CakePHP3のschema管理(Migrations)について

Posted at

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()を使う必要があります。

OK
class AddBirthdayToUsers extends AbstractMigration
{
    public function change()
        $table = $this->table('users');
        $table
            ->addColumn('birthday', 'date', [
                'default' => null,
                'limit' => null,
                'null' => true,
            ])
            ->update();
    }
}
NG
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
を見てください。

16
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?