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