将外键添加到Laravel中的现有表时,外键约束失败

时间:2019-12-23 10:45:13

标签: php database laravel eloquent migration

我有一张表order_lines,其中有一个属于orders的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外键(order_id)参考订单(id)在删除级联中) (SQL:更改表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;');

但是错误仍然存​​在。

enter image description here

1 个答案:

答案 0 :(得分:2)

您的问题是order_lines表中有一些记录具有{_1}表中不存在的order_ids。

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