web-dev-qa-db-ja.com

Laravel移行-整合性制約違反:1452子行を追加または更新できません:外部キー制約が失敗します

この移行で作成したテーブル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、CONSTRAINT inventories_local_id_foreign 外部キー (local_id)リファレンスcontentsid)ON DELETE CASCADE)(SQL:変更テーブルinventories追加制約inventories_local_id_foreign 外部キー (local_id)削除カスケードでcontentsid)を参照)

[PDOException]

SQLSTATE [23000]:整合性制約違反:1452子行を追加または更新できません:外部キー制約が失敗しました(middleton
.#sql-5d6_162a、CONSTRAINT inventories_local_id_foreign 外部キー (local_id)リファレンスcontentsid)ON DELETE CASCADE)

何が悪いのですか?

10
Leff

inventoriesテーブルに対応するidがないlocal_idを含むcontentsテーブルにレコードがある可能性があるため、エラーが発生します。次の2つの方法のいずれかで解決できます。

  • foreign_key_checksをオフにして移行を実行します。これにより、既存の行の外部キー制約が無効になります(必要な場合)。文書化されています ここ
  • idテーブルに対応するcontentsフィールドを持つレコードのみを挿入します。 INSERT INTO.. WHERE EXISTSクエリを使用してレコードを除外し、それらのレコードのみを挿入できます。
9
Darshan Mehta

同じ問題がありました。フィールドに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

11
Roman Bobrik