phinxを使ってみた(マイグレーション変)
とりあえずinstall
composer require robmorgan/phinx
initで初期化をするらしい。
vendor/bin/phinx init
phinx.php が生えた。
<?php return [ 'paths' => [ 'migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations', 'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds' ], 'environments' => [ 'default_migration_table' => 'phinxlog', 'default_environment' => 'development', 'production' => [ 'adapter' => 'mysql', 'host' => 'localhost', 'name' => 'production_db', 'user' => 'root', 'pass' => '', 'port' => '3306', 'charset' => 'utf8', ], 'development' => [ 'adapter' => 'mysql', 'host' => 'localhost', 'name' => 'development_db', 'user' => 'root', 'pass' => '', 'port' => '3306', 'charset' => 'utf8', ], 'testing' => [ 'adapter' => 'mysql', 'host' => 'localhost', 'name' => 'testing_db', 'user' => 'root', 'pass' => '', 'port' => '3306', 'charset' => 'utf8', ] ], 'version_order' => 'creation' ];
なるほど。
このフォーマットなら「他のFW(おいちゃんの想定はSlim)使ってて、そっちで(も)DBの接続設定がある」なんてケースでもちゃんとDRYに出来るねぇ!!
1点気になってたのが一瞬で氷塊したので、まぁ普通に「使う」前提でよいのではないかしらん???
見るに
・いったんのデフォはdevelopment
っぽいので、そのままテスト用のDBの設定をdevelopmentに書いて、追加で実験してみませう。
お次。
必要なディレクトリを作るぽ。
mkdir -p db/migrations db/seeds
これはまぁ実際には「このディレクトリもgitに登録しておく」とかで良さそうざます。
&
configの設定の「%%PHINX_CONFIG_DIR%%」がちょい気になるが、まぁなんかあったら後で出てくるでせう。
次。
眼目になるマイグレーションファイル作成。
本家サイトとか、アッパーキャメルなのがちょいと気になるなぁ……いったんヘビにしてみよう。
php vendor/bin/phinx create table_name
The migration class name "table_name" is invalid. Please use CamelCase format.
わをwww
キャメル固定なのかwww
では改めて。
php vendor/bin/phinx create TableName
Phinx by CakePHP - https://phinx.org.
using config file phinx.php
using config parser php
using migration paths
- /home/furu/PhinxTest/db/migrations
using seed paths
- /home/furu/PhinxTest/db/seeds
using migration base class Phinx\Migration\AbstractMigration
using default template
created db/migrations/20230819124347_table_name.php
ほむ……seedとmigrationsにファイルが出来てる? 確認。
seedには……ない。
なんじゃろ???
(後で分かった。ここ。seederを作る所なんだ)
migrationsにはファイルが出来てる。
<?php declare(strict_types=1); use Phinx\Migration\AbstractMigration; final class TableName extends AbstractMigration { /** * Change Method. * * Write your reversible migrations using this method. * * More information on writing migrations is available here: * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method * * Remember to call "create()" or "update()" and NOT "save()" when working * with the Table class. */ public function change(): void { } }
簡素だなをいw
んで、指定したのは純粋に「クラス名」なのか。それ以外の処理、なんもないw
軽く書いていこう。
書く場所は
・change() に書くと、(ある程度までは)マイグレーションを巻き戻す時、勝手に良い感じに巻き戻してくれる
・でなきゃ、おとなしく up() と donw() を書け
らしい。
で……ちょっと気になる記述も見かけたので、その辺の確認込みで、いくつか書いてみる。
public function change(): void { $table = $this->table('test'); $table->addColumn('name', 'string') ->addColumn('str', 'varchar', ['limit' => 128]) ->addColumn('str2', 'varbinary', ['limit' => 128]) ->addColumn('num', 'int', ['comment' => 'コメント']) ->addColumn('num2', 'bigint') ->addColumn('created_at', 'datetime') ->create(); }
ドライランがあるとの事で、早速やってみる。
あと、 -e での環境指定を「あえて」省略してみる(configにデフォ値あったし)。
php vendor/bin/phinx migrate --dry-run
InvalidArgumentException: An invalid column type "varchar" was specified for column "str".
あそ。
他いくつか修正。
public function change(): void { $table = $this->table('test'); $table->addColumn('name', 'string') ->addColumn('str', 'string', ['limit' => 128]) ->addColumn('str2', 'varbinary', ['limit' => 128]) ->addColumn('num', 'integer', ['comment' => 'コメント']) ->addColumn('num2', 'biginteger') ->addColumn('created_at', 'datetime') ->create(); }
CREATE TABLE `test` (
`id` INT(11) unsigned NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL,
`str` VARCHAR(128) NULL,
`str2` VARBINARY(128) NULL,
`num` INT(11) NULL COMMENT 'コメント',
`num2` BIGINT(20) NULL,
`created_at` DATETIME NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
あら?
うん前情報通り「勝手にID入れてくる」のは気になるが、VARBINARYに対応しているのはおいちゃん的に大分と高ポイントざますよ?
ほむ……ちょいと本気を出してみよう(実験用なんでテーブルレイアウトはきにすんな)。
public function change(): void { $table = $this->table('test', [ 'id' => false, 'primary_key' => 'test_id', 'comment' => 'テーブルコメント', ]); $table ->addColumn('test_id', 'biginteger', ['null' => false, 'signed' => false, 'identity' => true,]) ->addColumn('name', 'string') ->addColumn('str', 'string', ['limit' => 128, 'null' => false]) ->addColumn('str2', 'varbinary', ['limit' => 128]) ->addColumn('num', 'integer', ['comment' => 'コメント']) ->addColumn('num2', 'biginteger') ->addColumn('created_at', 'datetime', ['null' => false, 'default' => 'CURRENT_TIMESTAMP']) ->create(); // $table = $this->table('test_2', [ 'id' => false, 'primary_key' => ['test_id', 'str'], 'comment' => 'テーブルコメント', ]); $table ->addColumn('test_id', 'biginteger', ['null' => false, 'signed' => false, 'identity' => true,]) ->addColumn('str', 'string', ['limit' => 128, 'null' => false]) ->create(); }
CREATE TABLE `test` (
`test_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL,
`str` VARCHAR(128) NOT NULL,
`str2` VARBINARY(128) NULL,
`num` INT(11) NULL COMMENT 'コメント',
`num2` BIGINT(20) NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`test_id`)
) ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='テーブルコメント';CREATE TABLE `test_2` (
`test_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`str` VARCHAR(128) NOT NULL,
PRIMARY KEY (`test_id`,`str`)
) ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT='テーブルコメント';
よし、よし。
ちょっと調べるのに時間がかかったけど、大体いけるっぽいなぁ。
よしちゃんと実行してみやう。
php vendor/bin/phinx migrate
mysql> show tables; +----------------------+ | Tables_in_phinx_test | +----------------------+ | phinxlog | | test | | test_2 | +----------------------+ 3 rows in set (0.00 sec) mysql> show create table test \G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `test_id` bigint unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `str` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL, `str2` varbinary(128) DEFAULT NULL, `num` int DEFAULT NULL COMMENT 'コメント', `num2` bigint DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`test_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='テーブルコメント' 1 row in set (0.00 sec) mysql> show create table test_2 \G *************************** 1. row *************************** Table: test_2 Create Table: CREATE TABLE `test_2` ( `test_id` bigint unsigned NOT NULL AUTO_INCREMENT, `str` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`test_id`,`str`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='テーブルコメント' 1 row in set (0.00 sec)
んむんむ、よきよき。
一応、rollback
php vendor/bin/phinx rollback
mysql> show tables; +----------------------+ | Tables_in_phinx_test | +----------------------+ | phinxlog | +----------------------+ 1 row in set (0.01 sec)
よきよき。
一応メモ程度に残しておくと。
php vendor/bin/phinx migrate -e 環境名 php vendor/bin/phinx rollback -e 環境名
ってのが本来っぽい感じではあるので、一応。
ただまぁこれだと
・ステージングまでは普通に「コードupしてからマイグレーションする」
・本番は「先にマイグレーションしてからコードupする」
とかもできそうだなぁ……ちょいと運用も考えてみやう。
大雑把に
・「テーブル作る」とか「カラム追加する」くらいなら、change() に実装すればよさげ
・一応「SQLダイレクト発行」もある、みたいだけど、現状だとあんまりいらなさそうな雰囲気がある
・まぁ必要になったら「up()とdown()で実装しつつSQL書く」でよいんじゃなかろうか
って感じなので。
「便利な機能はあるけど簡単にoffれるから足かせにならないので気楽」って感じだなぁ。
うん、ちょいと使い込んでみてもよいかも。ちょっと癖があるから色々調べなきゃいかんけどw
次回はseederを確認してみませう。