Laravelのテーブルrename処理はmigrationファイルを分けた方が吉
このブログを放置しすぎているけど、久しぶりにハマったネタがあったので、更新しておこう。
Laravelでテーブルリネーム処理は、migrationファイル内で以下のように定義すれば良い。
Schema::rename('from_table_name','to_table_name');
このときテーブル名変更処理とカラム追加などの定義変更も同時にやろうと、同一migrationファイル内にリネーム処理と定義変更を以下のようにやってみた。
public function up() { Schema::rename('trn_reserv_rate_class_details','trn_reserv_time_rate_details'); Schema::table('trn_reserv_time_rate_details', function (Blueprint $table) { $table->renameColumn('reserv_rate_class_detail_id', 'reserv_rate_time_detail_id'); $table->unsignedInteger('reserv_time_class_id')->after('reserv_rate_class_id') ->references('reserv_time_class_id')->on('trn_reserv_time_classes') ->onupdate('restrict') ->ondelete('restrict'); $table->dropColumn(['start_time', 'end_time']); $table->dropForeign('trn_reserv_rate_class_details_reserv_rate_class_id_foreign'); $table->dropIndex('idx_reserv_rate_class_id_start_time_end_time'); }); }
このときにphp artisan migrateを実行してSchema::tableのテーブル内の定義変更の方でエラーになったりすると(インデックス削除処理の前に外部キー参照制約を消す定義をいれてなかったりでエラーになった)、テーブルリネーム処理だけが完了してしまう。migrationsテーブルを確認すると、このmigartionファイルの実行履歴はない。ということは、rollbackせずに再度php artisan migrateを実行できるはずだと思ってやってみると、すでにテーブルリネーム処理だけが完了しているので、テーブル名重複エラーになってしまう。
同様にphp artisan migrate:rollbackで実行するときのdown処理でもエラーになると、migrationsテーブルと実態のテーブルの状態がずれてしまって、rollback処理もうまくいかなくて、結局テーブル名を直接SQL文で変更するなり、対象テーブルを削除し、さらにmigrationsテーブルの履歴を削除したりして補正する手間が発生してしまった。
なので、テーブルリネーム処理とテーブル定義変更を同時にやる場合は、面倒だけどmigrationファイルを別に作ってそれぞれに定義して適切な順番で実行してやるとエラーになっても再度migaration, migaration:rollbackが問題なく実行できる。
この罠にハマって数時間浪費してしまったが、ネタができたと思っておこう。
あとはてなのソースコードのシンタックスハイライトにLaravel対応はないのかな?一応上記はPHPを指定しているのだけど。