PHP
laravel5

Laravel5でmigration実行時に外部ファイルのsqlを実行する

More than 1 year has passed since last update.

やったこと/サマリ

  • 別のサービスで使っているマスタデータをdumpで取得しmigration実行時にデータごと投入する
  • 投入は migrate の up() 内で exec コマンドで行う

背景

migrationは便利ですが初期データを入れるのにはseedと連携する必要があります。
また、seedもデータ数個程度であれば問題ないですが大量のデータを作成するのは面倒です。
特に、マスタ系の情報など、すでに他のDBに作成済みのテーブルやCSVファイルなどを大量に入れるには普通にSQL実行したほうが楽なのではと思っています。

今回は mysqldump で取得した SQL をそのまま migration 実行時に実行することで migration 実行時にデータ付きでテーブルを作成します

作業内容

dump ファイルの作成

mysqldumpコマンドでファイルを作成します。
mysqldump -u username -p dbname tablename > tablename

今回はdatabase/dump_dataディレクトリを作成し、そこにこのファイルを置いています。

migration の作成

migration ファイルを作成します

php artisan make:migration create_masters

up() にコマンドの追加

create_masters.php
$file_path = realpath(__DIR__.'/../dump_master/');
$file_name = 'tablename';
exec('mysql -u '.env('DB_USERNAME').' -p'.env('DB_PASSWORD').' '.env('DB_DATABASE').' < ' .$file_path.'/'.$tablename);

realpath(__DIR__) コマンドでmigrationファイルの存在するパスを取得できるので、そこからの相対パスでdumpファイルを取得します。

注意

.envファイルにDB_USERNAME, DB_PASSWORD, DB_DATABASEの値が設定されている必要があります。
特にDB_PASSWORDについては空文字だと正常に動作はしますが、
mysqlコマンドの -p オプションが「パスワードが空文字である」と認識できずenterキーを押す必要がでるため、
mysqlの設定込でパスワードを設定しておく必要があります。

migration の実行

php artisan migrateを実行すると動くことが確認できるかと思います。

他のやり方ないの?

もっと Laravel ぽい書き方がしたかったのですが、調べてもすぐには見つかりませんでした。
Issue with DB::unprepared() にかかれていますが、unprepared()を使うことでできるケースもあるみたいです。
ただバージョンなどでハンドリングが必要なのでこのやり方でもいいかと思います。

(もっとLaravelっぽくかっこよく書ける人いましたら教えてください!)

以上です。