lulco/phoenix でデータ関係が依存しているDBをマイグレーションする方法をメモ。
ドキュメントが全然ないので地道にやっていきます……。
コード
早速コードを。
phoenix.php
return [
'migration_dirs' => [
'first' => __DIR__ . '/migrations/first',
'second' => __DIR__ . '/migrations/second',
],
'environments' => [
'local' => [
'adapter' => 'mysql',
'host' => $_ENV['MYSQL_HOST'],
'port' => (int)$_ENV['MYSQL_PORT'], // optional
'username' => $_ENV['MYSQL_USER'],
'password' => $_ENV['MYSQL_PASSWORD'],
'db_name' => $_ENV['MYSQL_DBNAME'],
'charset' => 'utf8mb4',
],
'production' => [
'adapter' => 'mysql',
'host' => $_ENV['MYSQL_HOST'],
'port' => (int)$_ENV['MYSQL_PORT'], // optional
'username' => $_ENV['MYSQL_USER'],
'password' => $_ENV['MYSQL_PASSWORD'],
'db_name' => $_ENV['MYSQL_DBNAME'],
'charset' => 'utf8mb4',
],
],
'default_environment' => 'local',
'log_table_name' => 'phoenix_log',
];
肝は migration_dirs
で first
と second
でそれぞれ対応するディレクトリを指定しているところ。
/migrations/first/hoge.php
<?php
namespace migrations;
use Phoenix\Database\Element\Index;
use Phoenix\Migration\AbstractMigration;
class HogeMigration extends AbstractMigration
{
protected function up(): void
{
$this->table('hoge')
->addColumn('create_date', 'datetime')
->addColumn('name', 'string')
->create();
// insert
$hogeData = [
[
'name' => 'foo'
],
[
'name' => 'bar'
],
[
'name' => 'buz'
],
// 略
];
$rows = [];
foreach ($hogeData as $key => $val) {
$rows[] = [
'create_date' => date('Y-m-d H:i:s'),
'name' => $val['name'],
];
}
$this->insert('hoge', $rows);
}
protected function down(): void
{
$this->table('hoge')
->drop();
}
}
まずは最初に hoge
というDBを作成し、そこにデータを流し込みます。
/migrations/second/fuga.php
<?php
namespace migrations;
use Phoenix\Database\Element\Index;
use Phoenix\Migration\AbstractMigration;
class FugaMigration extends AbstractMigration
{
protected function up(): void
{
$this->table('fuga')
->addColumn('create_date', 'datetime')
->addColumn('name', 'string')
->addColumn('hoge_id', 'integer')
->create();
// select hoge data
$hogeRows = $this->select('SELECT id, name FROM hoge');
// insert
$fugaData = [
[
'name' => 'un'
],
[
'name' => 'deux'
],
[
'name' => 'trois'
],
// 略
];
$rows = [];
foreach ($fugaData as $key => $val) {
$id = 0;
// hoge の name と fuga の name が一致する要素を array_filter() で抽出し、 array_values() で番号を詰める
$hogeArray = array_values(
array_filter(
$hogeRows,
function($hogeRow) use ($val) {
$needle = mb_strlen(mb_strtolower($val[0])) > 0 ? mb_strtolower($val[0]) : 'NOTHING';
return mb_strpos(mb_strtolower($hogeRow['name']), $needle) !== false;
}
)
);
// $hogeArray の要素が1つ (一意に定まる) 場合はその値を、そうでない場合はデフォルト値をセット
$id = count($hogeArray) === 1 ? (int)$hogeArray[0]['id'] : 0;
$rows[] = [
'create_date' => date('Y-m-d H:i:s'),
'name' => $val[0],
'hoge_id' => $id, // 上述でセットした id を使用
];
}
$this->insert('fuga', $rows);
}
protected function down(): void
{
$this->table('fuga')
->drop();
}
}
次に fuga
を作成し、そこに徐に $this->select()
で SQL文 を発行、先程流し込んだデータを抽出します。
その抽出したデータと fuga
に流し込みたいデータを突き合わせて初期データを生成し、それを fuga
に流し込む……という算段。
これで意図したデータをマイグレーションすることができました。
参考
ドキュメントがないのでコードを読んで普通に select
とか使えそう、と思って試したりしていました。