Laravelで後から複数カラムにUNIQUE制約を追加する
migration作成
php artisan make:migration add_unique_constraints_to_post_records_table --table="post_records"
すると、以下のようなmigrationファイルができるので編集する。
/Users/w/workspace/t/approot/database/migrations/2018_07_08_190530_add_unique_constraints_to_post_records_table.php
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddUniqueConstraintsToPostRecordsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('post_records', function (Blueprint $table) { $table->unique(['plan_id', 'id_str']); }); } /** * Reverse the migrations. * * @return void */ public function down() Schema::table('post_records', function (Blueprint $table) { $table->dropUnique(['plan_id', 'id_str']); }); } }
migration実行
php artisan migrate
とすると
Illuminate\Database\QueryException : SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'PID-5B2-284-C16-2B5-5-1011252678360379399' for key 'post_records_plan_id_id_str_unique' (SQL: alter table `post_records` add unique `post_records_plan_id_id_str_unique`(`plan_id`, `id_str`))
となって怒られる。
alter table `post_records` add unique `post_records_plan_id_id_str_unique`(`plan_id`, `id_str`)
というSQLを発行し、既存のデータに重複が存在しているのでエラーになっている。
なので、既存のテーブルからなんとかして重複を排除する。
今回の場合、.envでDB情報を確認して、
1. 既存データベースの保存
/Applications/MAMP/Library/bin/mysqldump -u foo -p -B db > /Users/w/db_dump.sql
- 不要データの削除
/Applications/MAMP/Library/bin/mysql -u foo -p
USE db; TRUNCATE TABLE post_records;
として、重複データを削除する。 TRUNCATEは厳密にはテーブルをDROPして作り直す。
重複ならインサートしない
ってことにしたいので、INSERTする部分をtry, catchで囲む。
try { $pr->save(); } catch (\Exception $e) { /** Do nothing */ }
とかする。
教訓
最初のdb設計の段階でunique制約をしっかり指定すべし!