cakePHP4でマイグレーションをマスターしてテーブルの作成とかしたいけど、どうすればいいんだろう…
こんな疑問を解決します。
この記事を最後まで読めば、基本的なcakePHP4のマイグレーションは理解できます。
マイグレーションは、テーブル作成するアプリ作成の根幹機能なので、ぜひマスターしていきましょう。
具体的に解説する内容としては、
- マイグレーションでよく使う基本コマンド
- テーブル作成
- テーブル削除
- テーブルにカラム追加
- テーブルのカラム削除
- テーブルのカラムの型変更
この辺りを解説していきます。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
cakePHP4のマイグレーション基本コマンド
マイグレーションファイルの作成
bin/cake bake migration Createテーブル名
例)
bin/cake bake migration CreateUsers
Createテーブル名 …テーブルの作成
Dropテーブル名 …テーブルの削除
Addカラム名テーブル名 …指定のテーブルにカラムを追加する
Removeカラム名Fromテーブル名 …指定のテーブルからカラムを削除する
Alterカラム名Onテーブル名 …カラムの変更
マイグレーションの実行
bin/cake migrations migrate
ロールバック
bin/cake migrations rollback
マイグレーションのステータスを確認
bin/cake migrations status
【cakePHP4マイグレーション】テーブル作成
テーブル作成のためのマイグレーションファイルは以下のようにCreateテーブル名です。
試しにItemsテーブルを作成してみましょう。
$ bin/cake bake migarion CreateItems
config > Migrations配下に20220305080248_CreateItems.phpみたいにマイグレーションファイルが作成されます。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('items');
$table->create();
}
}
cakePHP4では、changeメソッド一つでLaravelのupとdownの処理を推測してくれる機能があります。なので、基本的にはchangeメソッドだけで大丈夫ですが、一部changeだけで対応できない処理もあるので、その場合はupとdownメソッドを書いていきます。
例)
public function up()
{
migrate実行時の処理
}
public function down()
{
ロールバック実行時の処理
}
このマイグレーションファイルを編集してマイグレーションを実行すれば、テーブルを作成できます。
idカラムは自動的に生成されるので、この状態でマイグレーションを実行すると、idカラムのみのitemsテーブルが作成されます。
$ bin/cake migrations migrate
itemsテーブルが作成されて、カラムもidのみあることが確認できました。
ただ、実際には、id以外のカラム(例えば、nameやpriceなど)も必要かと思うので基本的なカラムの型やnullを許容するかなどのオプションなどを紹介していきます。
itemsテーブルの内容はこの後変更するので、一度ロールバックしてテーブルを削除します。
bin/cake migrations rollback
データベースからitemsテーブルがない状態であることを確認しておきましょう。
テーブルにカラムを作る
テーブルのカラムを作る時はaddColumnでできます。
$table->addColumn('カラム名', '型', [
'オプション' => '',
'オプション' => '',
]);
よく使う代表的な型は以下です。
string | 文字列 |
integer, biginteger | 数値 |
text | テキスト |
boolean | 真(true)か偽(false) |
datetime, timestamp | 日付 |
よく使うオプションは以下です。
‘default’ => | デフォルト値を設定 |
‘limit’ => | 文字数や数値の制限など。stringやinteger型ともに使われる。 |
‘null’ => | nullを許容するかしないか |
‘comment’ => | カラムにコメントをつける |
上記を踏まえて、itemsのマイグレーションファイルを編集します。
itemsテーブルの構造のゴールはこんな感じです。
最初に作成したマイグレーションファイルを編集します。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('items');
// カラム名:name 型:varchar(255) デフォルト値:null NULL:× コメント:商品名
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
'comment' => '商品名',
]);
// カラム名:price 型:int デフォルト値:0 NULL:× コメント:価格
$table->addColumn('price', 'integer', [
'default' => 0,
'null' => false,
'comment' => '価格',
]);
// カラム名:content 型:text デフォルト値:null NULL:○ コメント:内容
$table->addColumn('content', 'text', [
'default' => null,
'null' => true,
'comment' => '内容',
]);
// カラム名:published 型:boolean デフォルト値:0 NULL:× コメント:公開・非公開
$table->addColumn('published', 'boolean', [
'default' => false,
'null' => false,
'comment' => '公開・非公開',
]);
// カラム名:created_at 型:datetime デフォルト値:null NULL:× コメント:作成日時
$table->addColumn('created_at', 'datetime', [
'default' => null,
'null' => false,
'comment' => '作成日時',
]);
// カラム名:updated_at 型:datetime デフォルト値:null NULL:○ コメント:更新日時
$table->addColumn('updated_at', 'datetime', [
'default' => null,
'null' => true,
'comment' => '更新日時',
]);
$table->create();
}
}
マイグレーションを実行します。
$ bin/cake migrations migrate
データベースを確認すると、
このようになっていれば成功です。
念のため、マイグレーションのステータスも確認しておきます。
$ bin/cake migrations status
using migration paths
- /html/config/Migrations
using seed paths
- /html/config/Seeds
using environment default
Status Migration ID Migration Name
-----------------------------------------
up 20220305080248 CreateItems
ユニーク制約
ユニーク制約をつける場合は、こんな感じでかけます。
public function change()
{
$table = $this->table('users');
$table->addColumn('email', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->create();
// emailにユニーク制約追加
$table->addIndex('email', [
'name' => 'unique_mail',
'unique' => true,
]);
$table->update();
}
【cakePHP4マイグレーション】テーブル削除
テーブルの削除をするためのマイグレーションファイルは以下で作成できます。
$ bin/cake bake migration Dropテーブル名
と、その前にitemsテーブルはこの後も使うので、代わりにshopsテーブルを作成しそれを削除しましょう。
$ bin/cake bake migration CreateShops
shopsのマイグレーションファイルを編集します。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class CreateShops extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('shops');
$table->addColumn('shop_name', 'string', [
'null' => true,
]);
$table->create();
}
}
マイグレーションを実行します。
$ bin/cake migrations migrate
データベースにidとnameカラムを持ったshopsテーブルができます。
準備ができたので、shopsテーブルを削除するマイグレーションファイルを作成します。
$ bin/cake bake migration DropShops
マイグレーションファイルができるので、編集します。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class DropShops extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function up()
{
$table = $this->table('shops');
$table->drop()
->save(); // save()がないとdropされない。
}
public function down()
{
$table = $this->table('shops');
$table->addColumn('shop_name', 'string', [
'null' => true,
]);
$table->create();
}
}
ポイントは、$table->drop()
->save();
と、save()を忘れないことです。
もし、$table->drop();だけだと、テーブルは削除されません。
それと、changeメソッドではなく、up/downメソッドを書くことも大事です。
changeだとrollbackでこけます。
マイグレーションを実行します。
$ bin/cake migrations migrate
DBからshopsテーブルが消えます。
ロールバックを実行すると、shopsテーブルは復活します。
$ bin/cake migrations rollback
【cakePHP4マイグレーション】既存テーブルにカラムを追加
既存のテーブルにカラムを追加する方法は、
$ bin/cake bake migration Add追加するカラム名To追加先のテーブル名
これでカラム追加用のマイグレーションファイルが作成されます。
itemsテーブルに商品を作った会社名のカラムを追加する想定の場合、
$ bin/cake bake migration AddCompanyToItems
でマイグレーションファイルが作成されます。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class AddCompanyToItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('items');
$table->update();
}
}
マイグレーションファイルを編集していきます。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class AddCompanyToItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('items');
$table->addColumn('company_name', 'string', [
'default' => null,
'limit' => 50,
'null' => false,
'comment' => '会社名',
'after' => 'name', // nameカラムの後にcompany_nameを追加できる
]);
$table->update();
}
}
カラムを追加する際は、afterオプションをつけて任意のカラムの後に追加するように指定しましょう。でないと、company_nameはupdated_atの後に追加されて気持ち悪いです。
$ bin/cake migrations migrate
カラムが追加できました。
【cakePHP4マイグレーション】既存テーブルのカラムを削除
既存テーブルのカラムを削除するために、カラム削除用のマイグレーションファイルを作成します。
$ bin/cake bake migration Remove削除するカラム名Fromテーブル名 (カラム名)
例)
$ bin/cake bake migration RemoveCompanyNameFromItems company_name
// 最後のカラム名はなくてもマイグレーションファイルは作成できる。
$ bin/cake bake migration RemoveCompanyNameFromItems
最後のカラム名を打った場合と打たない場合の違い
bin/cake bake migration RemoveCompanyNameFromItems company_nameとした場合
$table = $this->table('items');
$table->update();
bin/cake bake migration RemoveCompanyNameFromItemsとした場合
$table = $this->table('items');
$table->removeColumn('company_name');
$table->update();
カラム名を打った方が、$table->removeColumn(‘カラム名’)を自動的に追加してくれます。
$ bin/cake bake migration RemoveCompanyNameFromItems company_name
カラム削除用のマイグレーションファイルが作成されます。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class RemoveCompanyNameFromItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('items');
$table->removeColumn('company_name');
$table->update();
}
}
カラムの削除の場合、changeメソッドだけだとマイグレーションの実行はできてもrollbackでこけます。なので、up/downメソッドを書く必要があります。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class RemoveCompanyNameFromItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function up()
{
$table = $this->table('items');
$table->removeColumn('company_name');
$table->update();
}
public function down()
{
$table = $this->table('items');
$table->addColumn('company_name', 'string', [
'default' => null,
'limit' => 50,
'null' => false,
'comment' => '会社名',
'after' => 'name',
]);
$table->update();
}
}
removeColumnでカラムを削除できます。
rollback時の処理はdownに書いていますが、カラム追加で説明した内容と同じなので省略します。
$ bin/cake migrations migrate
マイグレーションを実行すると、itemsテーブルからcompany_nameカラムが消えます。
$ bin/cake migrations rollback
ロールバックを実行すると、company_nameが復活します。
【cakePHP4マイグレーション】既存テーブルのカラムを変更
既存テーブルのカラムを変更するマイグレーションファイルを作成していきます。
$ bin/cake bake migration Alterカラム名Onテーブル名 (カラム名:型)
itemsテーブルのpriceカラムを以下のように変更します。
・型の変更:integer→biginteger
・NULL制約の変更:null→falseからnull→trueに
・符号なしの追加(unsigned)
・コメント:価格→商品価格
$ bin/cake bake migration AlterPriceOnItems price:biginteger
マイグレーションファイルが作成されるので、以下のように修正します。
カラムを削除する時と同様、changeメソッドだけだとマイグレーションは実行できますが、rollbackでこけるので、upとdownメソッドを書きます。
<?php
declare(strict_types=1);
use Migrations\AbstractMigration;
class AlterPriceOnItems extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function up()
{
$table = $this->table('items');
$table->changeColumn('price', 'biginteger', [
'default' => 0,
'limit' => 20,
'null' => true,
'signed' => false,
'comment' => '商品価格'
]);
$table->update();
}
public function down()
{
$table = $this->table('items');
$table->changeColumn('price', 'integer', [
'default' => 0,
'null' => false,
'comment' => '価格',
]);
$table->update();
}
}
マイグレーションを実行します。
$ bin/cake migrations migrate
priceカラムが変更されていることが確認できます。
ロールバックすると、元のpriceのカラムに戻ることが確認できます。
$ bin/cake migrations rollback
これで実務の開発もスムーズにできます。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント