Laravel迁移(错误:150“外键约束形成错误”)

问题描述 投票:4回答:8

我有一个订单表和一个sell_shipping_labels引用orders.id作为外国。但是,当我运行Laravel迁移时,我得到了可怕的错误代码:

[照亮\数据库\ QueryException] SQLSTATE [HY000]:常规错误:1005无法创建表cheapbooks_test.#sql-b5b_b2a(错误:150“外键约束形成错误”)(SQL:alter table sell_shipping_labels add constraint sell_shipping_labels_order_id_foreign foreign key(order_id)references ordersid))

[学说\ DBAL \驱动\ PDOException] SQLSTATE [HY000]:常规错误:1005无法创建表cheapbooks_test.#sql-b5b_b2a(错误号:150“外键约束形成错误”)

这是我的orders表架构:

   Schema::create('orders', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id');
        $table->integer('book_id');
        $table->integer('status_id');
        $table->double('payment_amount')->nullable();
        $table->timestamp('received_at')->nullable();
        $table->timestamp('paid_at')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });

这是我的sell_shipping_labels架构:

Schema::create('sell_shipping_labels', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('order_id');
        $table->string('shippo_object_id');
        $table->string('label_url');
        $table->string('tracking_url');
        $table->string('tracking_number');
        $table->timestamp('arrived_at');
        $table->timestamps();
        $table->softDeletes();

        $table->foreign('order_id')->references('id')->on('orders');
    });
}

现在我已经颠倒了互联网,试图找出问题所在。关于这个问题的所有帖子都提到了这样一个事实,即必须在具有外键的表之前创建订单表,但这对我来说不是问题,因为我的文件的顺序正确。

mysql laravel laravel-5 artisan artisan-migrate
8个回答
20
投票

由于increments()创建了无符号整数列,因此您还需要将外键列定义为无符号整数:

$table->unsignedInteger('order_id');

要么:

$table->integer('order_id')->unsigned();

https://laravel.com/docs/5.5/migrations#foreign-key-constraints


0
投票

对于使用laravel 5.8.x查看此内容的任何人,我通过更改此修复此问题

$table->unsignedInteger('foreign_id');

对此

$table->unsignedBigInteger('foreign_id');

这是由于使用了bigIncrements。相反,您可以删除偶然bigIncrements在关系两侧递增的机会


3
投票

外键必须是“unsignedBigInteger”,它将被修复,如下所示:

$table->unsignedBigInteger('user_id');

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

2
投票

我也得到了同样的错误。我在用户表中做的是,

$table->unsignedInteger('role_id')->default(2); table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');

但是我在创建用户表后创建了角色表。因此,我在用户表文件名日期之前编辑了角色迁移文件名日期。像这样,

2013_01_22_091213_create_roles_table.php 2014_10_12_000000_create_users_table.php

最后它有效。也许有时你可能会遇到这个问题。所以,我发布了它。


2
投票

Laravel 5.8.3附带$table->bigIncrements('id');

改为

$table->increments('id');
$table->integer('order_id')->unsigned();

1
投票

检查迁移的顺序。如果您的migrate命令试图在orders表之前生成sell_shipping_labels表,那么MySQL将会出现这种情况。它似乎继续创建迁移日期,从最旧到最新。换句话说,它试图引用的表上的order_id应该存在。

我遇到了同样的问题,我更改了创建迁移日期。


0
投票

对于那些标记答案不起作用的人:

检查你的表引擎。在我的例子中,我在InnoDB源表中的MyISAM表上引用。将参考表引擎更改为InnoDB后,它工作正常!


0
投票
  1. 应该以这样的方式创建迁移文件:首先是父迁移,然后是带有外键的迁移文件。
  2. 外键和另一个表中的主要ID应具有完全相似的属性。如果主要id是增量,则使外键整数('xxx_id') - > unsigned();

0
投票

我遇到了同样的问题并修复了将数据库类型设置为innoDB的问题

在迁移之前创建的表格中,默认情况下来自遗留系统和迁移的MyISAM是innoDB,因此在我的情况下,表格类型的混合是一个问题。


0
投票

我今天遇到了这个问题。我检查了所有建议的解决方案,例如引用的密钥和外键相同的数据类型,数据库引擎中的相同排序规则和laravel配置(database.php),迁移的日期顺序和其他可能的错误,但是任何人都是我的解决方案!我发现的最后一件事是onUpdate和onDelete约束,这些约束放在了迁移中。删除它们我的问题解决了!

© www.soinside.com 2019 - 2024. All rights reserved.