tag:crieit.net,2005:https://crieit.net/tags/%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/feed 「マイグレーション」の記事 - Crieit Crieitでタグ「マイグレーション」に投稿された最近の記事 2022-05-19T23:55:46+09:00 https://crieit.net/tags/%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/feed tag:crieit.net,2005:PublicArticle/18194 2022-05-19T23:55:46+09:00 2022-05-19T23:55:46+09:00 https://crieit.net/posts/php-phoenix-migrate-db-depend-other-db-20220521 (PHP) Phoenix でデータ関係が依存しているDBをマイグレーションする <p><a target="_blank" rel="nofollow noopener" href="https://github.com/lulco/phoenix">lulco/phoenix</a> でデータ関係が依存しているDBをマイグレーションする方法をメモ。</p> <p>ドキュメントが全然ないので地道にやっていきます……。</p> <h2 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h2> <p>早速コードを。</p> <h3 id="phoenix.php"><a href="#phoenix.php">phoenix.php</a></h3> <pre><code class="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', ]; </code></pre> <p>肝は <code>migration_dirs</code> で <code>first</code> と <code>second</code> でそれぞれ対応するディレクトリを指定しているところ。</p> <h3 id="/migrations/first/hoge.php"><a href="#%2Fmigrations%2Ffirst%2Fhoge.php">/migrations/first/hoge.php</a></h3> <pre><code class="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(); } } </code></pre> <p>まずは最初に <code>hoge</code> というDBを作成し、そこにデータを流し込みます。</p> <h3 id="/migrations/second/fuga.php"><a href="#%2Fmigrations%2Fsecond%2Ffuga.php">/migrations/second/fuga.php</a></h3> <pre><code class="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(); } } </code></pre> <p>次に <code>fuga</code> を作成し、そこに徐に <code>$this->select()</code> で SQL文 を発行、先程流し込んだデータを抽出します。</p> <p>その抽出したデータと <code>fuga</code> に流し込みたいデータを突き合わせて初期データを生成し、それを <code>fuga</code> に流し込む……という算段。</p> <p>これで意図したデータをマイグレーションすることができました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/lulco/phoenix">GitHub - lulco\/phoenix: Framework agnostic database migrations for PHP.</a> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/lulco/phoenix/blob/master/src/Database/Adapter/PdoAdapter.php">phoenix\/PdoAdapter.php at master · lulco\/phoenix · GitHub</a></li> </ul></li> </ul> <p>ドキュメントがないのでコードを読んで普通に <code>select</code> とか使えそう、と思って試したりしていました。</p> arm-band