Laravel 迁移 - 违反完整性约束:1452 无法添加或更新子行:外键约束失败

Laravel migration - Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails

我正在尝试 运行 为我使用此迁移创建的 table 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();
});

我正在尝试添加一个 运行 迁移,我正在向 table 添加一个外键:

Schema::table('inventories', function (Blueprint $table) {
    $table->foreign('local_id')->references('id')->on('contents')->onDelete('cascade');
});

但是,当我尝试 运行 迁移时出现错误:

[Illuminate\Database\QueryException]

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (middleton
.#sql-5d6_162a, CONSTRAINT inventories_local_id_foreign FOREIGN KEY (local_id) REFERENCES contents (id) ON DELETE CASCADE ) (SQL: alter table inventories add constraint inventories_local_id_foreign foreign key (local_id) references contents (id) on delete cascade)

[PDOException]

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (middleton
.#sql-5d6_162a, CONSTRAINT inventories_local_id_foreign FOREIGN KEY (local_id) REFERENCES contents (id) ON DELETE CASCADE )

我做错了什么?

您可能在 inventories table 中有一些记录 local_idcontents table 中没有相应的 id ,因此错误。您可以通过以下两种方式之一解决它:

  • 运行 foreign_key_checks 的迁移已关闭。这将禁用现有行的外键约束(如果这是你想要的)。已记录 here
  • 仅插入那些在 contents table 中具有相应 id 字段的记录。您可以使用 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

UPD:

因为 Laravel 7 有更多的捷径可以做同样的事情:

$table->foreignId('some_id')->nullable()->constrained();

nullableconstrained 之前也很重要。

您可以在 official documentation

中找到更多信息