【问题标题】:Foreign key constraint fails when adding a foreign key to an existing table in Laravel将外键添加到 Laravel 中的现有表时,外键约束失败
【发布时间】:2020-04-14 15:52:48
【问题描述】:

我有一个表 order_lines,其中有一个 order_id 属于订单。 现在我忘记在初始迁移中添加外键,现在网站已经启动并运行,并且数据库中有生命数据。

我要添加的外键会在删除订单时删除订单行。

我创建了以下迁移add_order_lines_order_id_foreign_to_order_lines_table

class AddOrderLinesOrderIdForeignToOrderLinesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('order_lines', function (Blueprint $table) {
            $table->foreign('order_id', 'order_lines_order_id_foreign')->references('id')->on('orders')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('order_lines', function (Blueprint $table) {
            $table->dropForeign('order_lines_order_id_foreign');
        });
    }
}

唯一要做的事情就是(试图)添加一个外键约束,这样当未来的订单被删除时,order_lines 也会随之删除。

这是我在尝试运行迁移时收到的错误

SQLSTATE[23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败(bud001_miguel.#sql-5e1_109923,CONSTRAINT order_lines_order_id_foreign FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE) (SQL:alter table order_lines 添加约束 order_lines_order_id_foreign 外键(order_id)在删除级联时引用订单(id))

这是原来的orders表定义

class CreateOrdersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id')->nullable();
            $table->unsignedBigInteger('shipping_address_id')->nullable();
            $table->unsignedBigInteger('billing_address_id')->nullable();
            $table->text('shipping_address_data')->nullable();
            $table->text('billing_address_data')->nullable();
            $table->timestamps();
        });

        Schema::table('orders', function (Blueprint $table) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
            $table->foreign('shipping_address_id')->references('id')->on('addresses')->onDelete('set null');
            $table->foreign('billing_address_id')->references('id')->on('addresses')->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('orders');
    }
}

这是原来的order_lines 表定义

class CreateOrderLinesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('order_lines', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('order_id');
            $table->unsignedBigInteger('animal_id');
            $table->unsignedBigInteger('product_plan_id');
            $table->unsignedInteger('price');
            $table->unsignedInteger('daily_price');
            $table->text('animal_data')->nullable();
            $table->text('plan_data')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('order_lines');
    }
}

我尝试过的

  • 通过将以下语句添加到迁移来禁用外键检查 DB::statement('SET FOREIGN_KEY_CHECKS=0;');

但错误仍然存​​在。

【问题讨论】:

  • 订单表中的order_linesid 的类型完全相同吗?
  • 是的,它们都是 BigInteger,我会将原始表定义添加到我的问题中
  • 在添加外键之前尝试添加$table->bigInteger('order_lines')->unsigned()->change();
  • 问题是orders 表中不存在某些order_id 值。首先运行一个查询来找到它们并处理它们,然后迁移
  • @FatemehMajd 这就是解决方案,请对此做出回答,以便我接受。

标签: php database laravel eloquent migration


【解决方案1】:

您的问题是order_lines 表中有一些带有order_ids 的记录在orders 表中不存在。

迁移尝试强制执行外键但不能。运行查询以查找这些行并处理它们,然后再次运行迁移

【讨论】:

  • 这就是解决办法,谢谢!如果您愿意,可以添加查询以查找这些记录:select * from order_lines where order_id not in (select id from orders);
  • or: select * from order_lines ol left join orders o on o.id=ol.order_id where o.id is null;
猜你喜欢
  • 1970-01-01
  • 2019-12-06
  • 2016-08-17
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 2021-06-11
相关资源
最近更新 更多