この移行で作成したテーブルinventories
の移行を実行しようとしています。
Schema::create('inventories', function (Blueprint $table) {
$table->increments('id');
$table->integer('remote_id')->unsigned();
$table->integer('local_id')->unsigned();
$table->string('local_type');
$table->string('url')->nullable()->unique();
$table->timestamps();
});
テーブルに外部キーを追加する実行移行を追加しようとしています。
Schema::table('inventories', function (Blueprint $table) {
$table->foreign('local_id')->references('id')->on('contents')->onDelete('cascade');
});
しかし、移行を実行しようとするとエラーが発生します。
[Illuminate\Database\QueryException]
SQLSTATE [23000]:整合性制約違反:1452子行を追加または更新できません:外部キー制約が失敗しました(
middleton
.#sql-5d6_162a
、CONSTRAINTinventories_local_id_foreign
外部キー (local_id
)リファレンスcontents
(id
)ON DELETE CASCADE)(SQL:変更テーブルinventories
追加制約inventories_local_id_foreign
外部キー (local_id
)削除カスケードでcontents
(id
)を参照)[PDOException]
SQLSTATE [23000]:整合性制約違反:1452子行を追加または更新できません:外部キー制約が失敗しました(
middleton
.#sql-5d6_162a
、CONSTRAINTinventories_local_id_foreign
外部キー (local_id
)リファレンスcontents
(id
)ON DELETE CASCADE)
何が悪いのですか?
inventories
テーブルに対応するid
がないlocal_id
を含むcontents
テーブルにレコードがある可能性があるため、エラーが発生します。次の2つの方法のいずれかで解決できます。
foreign_key_checks
をオフにして移行を実行します。これにより、既存の行の外部キー制約が無効になります(必要な場合)。文書化されています ここid
テーブルに対応するcontents
フィールドを持つレコードのみを挿入します。 INSERT INTO.. WHERE EXISTS
クエリを使用してレコードを除外し、それらのレコードのみを挿入できます。同じ問題がありました。フィールドにnullable
を追加して修正しました
Schema::create('table_name', function (Blueprint $table) {
...
$table->integer('some_id')->unsigned()->nullable();
$table->foreign('some_id')->references('id')->on('other_table');
...
});
移行後、存在するすべての行にはsome_id = NULL