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

时间:2017-12-09 13:09:22

标签: mysql laravel laravel-5 artisan artisan-migrate

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

  

[照亮\数据库\ QueryException]
    SQLSTATE [HY000]:常规错误:1005无法创建表cheapbooks_test#sql-b5b_b2a(错误:150"外键约束形成错误")(SQL:alter table sell_shipping_labels添加约束sell_shipping_labels_order_id_foreign外键(order_id)引用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');
    });
}

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

20 个答案:

答案 0 :(得分:13)

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

$table->unsignedInteger('order_id');

或者:

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

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

答案 1 :(得分:2)

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

将其更改为

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

答案 2 :(得分:1)

我也遇到了同样的错误。我在 users 表中所做的是

$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

最后它起作用了。也许有时您可能会遇到此问题。所以,我张贴了它。

答案 3 :(得分:1)

检查迁移顺序。如果您的migrate命令试图在orders表之前创建sell_shipping_labels表,则这将在MySQL中发生。它似乎在创建迁移日期,从最早到最新。换句话说,它要引用的表上的order_id应该存在。

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

答案 4 :(得分:1)

外键必须是“ unsignedBigInteger”,并且将被固定, 像这样的东西:

$table->unsignedBigInteger('user_id');

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

答案 5 :(得分:1)

大多数情况下,导致此错误的原因通常是由于迁移文件的列出顺序或类型转换导致的错误。

始终确保在父级迁移之后进行要施加外部约束的文件的迁移。 对于后者,请确保其为 unsignedBigInteger ,尽管以前的laravel版本(<5.4)可以忽略此类型转换错误。

答案 6 :(得分:0)

我今天遇到了同样的问题。我的Laravel版本是5.8.29。我通过以下方法解决了这个问题:

$table->bigIncrements('id'); //current table primary key and id
$table->unsignedBigInteger('user_id'); // foreigh key
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

希望这行得通。

答案 7 :(得分:0)

避免使用简单的所有这两行代码 这意味着 sell_shipping_labels.order_id 表中的 orders 引用 id 如下

Schema::table('sell_shipping_labels', function (Blueprint $table) {
    $table->foreignId('order_id')->constrained('orders');
});

答案 8 :(得分:0)

我的问题在我使用的时候解决了 bigInteger('user_id')->unsigned();

答案 9 :(得分:0)

在Laravel中添加外键的更好方法是使用别名。所以代替:

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

我们可以简单地做到这一点:

$table->foreignId('user_id')->constrained();

那对我有用。谢谢!

答案 10 :(得分:0)

对于laravel 6+用户,我同意前2个答案,这完全取决于laravel版本。对于最新版本,用户id列使用big integer。因此,从当前迁移中引用用户id时,您需要使用unsignedBigInteger作为参考键。 Bellow是 laravel 6.5。* 的迁移示例,每当我们分配foreign key时,请记住您的当前laravel版本

Schema::create('galleries', function (Blueprint $table) {
        $table->bigIncrements('id');
        ==>$table->unsignedBigInteger('user_id');
        $table->string('title');
        $table->string('description');
        $table->timestamps();
        ==>$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });

答案 11 :(得分:0)

我今天遇到了这个问题。我的父表主键数据类型和子表数据类型相同,但错误仍然存​​在。我发现我的父表和子表存储引擎不同。我已经通过从phpmyadmin中创建两个表存储引擎InnoDB来解决此问题。

答案 12 :(得分:0)

[![enter image description here][1]][1]
public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();


        });
    }

I changed $table->bigIncrements('id') to $table->Increments('id')
For this user_id of files table become same integer type as user table field id. After this command worked.

   public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }



For the second table
 {
        Schema::create('files', function (Blueprint $table) {
            $table->increments('id');

});

            Schema::table('files', function($table) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
           });
    }

enter image description here

答案 13 :(得分:0)

如果问题仍然没有解决,请尝试一下。 您需要创建最后一个关联的表。

您应该先创建订单,然后再创建sell_shipping_labels表

要解决此问题,您应该将“类别”和“用户”的迁移文件重命名为创建餐前表的“餐前迁移”文件的日期。

答案 14 :(得分:0)

主键和外键应使用相同的数据类型

如果主键使用的是未签名的big_integer,那么外键也应该使用的是未签名的big_integer

如果laravel 5.8在生成新迁移时默认使用bigIncrements(请参阅此pull request),则应确保foreign key也是big_increment,否则您将出错。

users

Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');

    ...

}

orders

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

    ...

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

希望这会有所帮助。

答案 15 :(得分:0)

使用laravel 5.8.x的读者 我通过更改来解决此问题 这个

$table->unsignedInteger('foreign_id');

对此

$table->unsignedBigInteger('foreign_id');

那是由于使用了bigIncrements。 相反,您可以删除在关系两侧的bigIncrements增量

答案 16 :(得分:0)

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

答案 17 :(得分:0)

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

的问题

在迁移之前创建的表(默认情况下,旧系统的MyISAM和已迁移的表是innoDB,因此,表类型的混合是我的问题。

答案 18 :(得分:0)

  1. 创建迁移文件的方式应使父迁移首先出现,而迁移文件带有外键。
  2. 另一个表中的外键和主ID应该具有完全相似的属性。如果主要ID为增量,则使外键为整数('xxx_id')-> unsigned();

答案 19 :(得分:0)

对于标有答案的用户无效:

检查表格引擎。就我而言,我引用的是 InnoDB 源表中的 MyISAM 表。将引用表引擎更改为InnoDB之后,它就起作用了!