提问者:小点点

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();
});

我正在尝试添加一个run a迁移,其中我正在向表中添加一个外键:

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

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

[照亮\Database\QueryException]

SQLState[23000]:完整性约束冲突:1452无法添加或更新子行:外键约束失败(middleton
.#SQL-5D6_162A,constraintinventories_local_id_foreign外键(local_id)引用删除级联时的contents(local_id)引用contents(id)(SQL:alter

[PDOException]

SQLState[23000]:完整性约束冲突:1452无法添加或更新子行:外键约束失败(middleton
.#SQL-5D6_162A,constraintinventories_local_id_foreign删除级联时的外键(local_id)引用contents(id

我做错了什么?


共2个答案

匿名用户

您可能在inventories表中有一些记录,其local_idcontents表中没有相应的id,因此出现错误。您可以通过以下两种方法之一来解决问题:

  • 在关闭foreign_key_checks的情况下运行迁移。这将禁用现有行的外键约束(如果需要的话)。这里有文档
  • 仅插入在contents表中具有相应ID字段的那些记录。您可以使用插入到..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();

同样非常重要的是,nullable位于constraint之前。

更多信息可以在官方文档中找到