如何修复laravel迁移中的外键错误

Posted

技术标签:

【中文标题】如何修复laravel迁移中的外键错误【英文标题】:how to fix foreign key error in laravel migration 【发布时间】:2020-11-07 17:30:10 【问题描述】:

我有一个订单表,我之前创建了这个表,但有时我必须更改我的迁移。

这是我更改前的订单表

Schema::create('orders', function (Blueprint $table) 
        $table->id();

        $table->unsignedBigInteger('user_id');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

        $table->bigInteger('price');
        $table->enum('status', ['unpaid', 'paid', 'preparation', 'posted', 'recieved', 'canceled']);
        $table->string('tracking_serial')->nullable();

        $table->timestamps();
    );

    Schema::create('order_product', function (Blueprint $table) 
        $table->unsignedBigInteger('product_id');
        $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

        $table->unsignedBigInteger('order_id');
        $table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');

        $table->integer('quantity');

        $table->primary(['product_id', 'order_id']);
    );

这是更改后的订单表

Schema::create('orders', function (Blueprint $table) 
        $table->id();

        $table->unsignedBigInteger('user_id');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

        $table->unsignedBigInteger('address_id');
        $table->foreign('address_id')->references('id')->on('addresses')->onDelete('cascade');

        $table->bigInteger('price');
        $table->string('post_type');
        $table->enum('status', ['unpaid', 'paid', 'preparation', 'posted', 'recieved', 'canceled']);
        $table->string('tracking_serial')->nullable();

        $table->primary(['user_id', 'address_id']);

        $table->timestamps();
    );

    Schema::create('order_product', function (Blueprint $table) 
        $table->unsignedBigInteger('product_id');
        $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

        $table->unsignedBigInteger('order_id');
        $table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');

        $table->integer('quantity');

        $table->primary(['product_id', 'order_id']);
    );

如您所见,我在 orders 架构中导入了 3 条新行:

$table->unsignedBigInteger('address_id');
$table->foreign('address_id')->references('id')->on('addresses')->onDelete('cascade');

$table->string('post_type');

$table->primary(['user_id', 'address_id']);

但是当我想运行 php artisan migrate 时,我得到了这个错误:

SQLSTATE[HY000]: General error: 1005 Can't create table `shop`.`orders` (errno: 150 "Foreign key 
constraint is incorrectly formed") (SQL: alter table `orders` add constraint 
`orders_address_id_foreign` foreign key (`address_id`) references `addresses` (`id`) on delete 
cascade)

为什么会出现这个错误?

更新:

这是我的地址表:

Schema::create('addresses', function (Blueprint $table) 
        $table->id();
        $table->string('state');
        $table->string('city');
        $table->text('address');
        $table->integer('plaque');
        $table->string('postal');
        $table->timestamps();
    );

    Schema::create('address_user', function (Blueprint $table) 
        $table->id();

        $table->unsignedBigInteger('user_id');
        $table->foreign('user_id')->references('id')->on('users')
        ->onDelete('cascade');
        $table->unsignedBigInteger('address_id');
        $table->foreign('address_id')->references('id')->on('addresses')
        ->onDelete('cascade');
        $table->primary(['user_id', 'address_id']);

        $table->timestamps();
    );

并在地址之前进行顺序迁移。

【问题讨论】:

“地址”的迁移在哪里? 问题出在您的addreses 表上,可能是您稍后创建的(在迁移orders 表之前)。或者你的主键格式不正确 @lagbox 问题已更新 【参考方案1】:

我希望您使用迁移来更改订单表,而不仅仅是修改原始迁移?

这个错误的发生通常有几个原因:

    fk 字段(address_id)和 pk 字段(即地址)不是同一类型 订单迁移在地址表之前运行(我认为在这种情况下不太可能,因为错误会有所不同) address_id 不可为空(据我所知),因此当您创建 FK 时,当前存在的行将没有有效的 FK 来寻址。 (所以让它可以为空)

【讨论】:

是的,我的订单表运行在地址表之前,我该怎么办 我在订单表之前运行地址表,我的问题解决了。谢谢 @Waltun 跟进——您可以将地址迁移的时间戳更改为订单表之前..【参考方案2】:

必须先创建表,再创建外键:

Schema::create('orders', function (Blueprint $table) 
        $table->id();
        $table->unsignedBigInteger('user_id');
        $table->unsignedBigInteger('address_id');
        $table->bigInteger('price');
        $table->string('post_type');
        $table->enum('status',['unpaid','paid','preparation','posted', 'recieved', 'canceled']);
        $table->string('tracking_serial')->nullable();
        $table->primary(['user_id', 'address_id']);
        $table->timestamps();
    );


Schema::table('orders', function (Blueprint $table) 

        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('address_id')->references('id')->on('addresses')->onDelete('cascade');
    );

【讨论】:

以上是关于如何修复laravel迁移中的外键错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4迁移问题中的外键

SQLSTATE [HY000] Laravel 8 中的外键约束格式错误

Laravel 5.2 迁移:无法添加 char 数据类型的外键

如何修复 MySQL 中的外键错误?

:完整性约束违规:1452 无法添加或更新子行:laravel 迁移中的外键约束失败

Laravel 5.3,MySQL,迁移中正确的外键设置(一对多,多对多)