Laravel 迁移(错误号:150 "Foreign key constraint is incorrectly formed")
Laravel migration (errno: 150 "Foreign key constraint is incorrectly formed")
我有一个订单 table 和一个 sell_shipping_labels
将 orders.id
引用为外国人。但是,当我 运行 Laravel 迁移时,我得到了可怕的错误代码:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table cheapbooks_test
.#sql-b5b_b2a
(errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table sell_shipping_labels
add constraint sell_shipping_labels_order_id_foreign
foreign key (order_id
) references orders
(id
))
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table cheapbooks_test
.#sql-b5b_b2a
(errno: 150 "Foreign key constraint is incorrectly formed")
这是我的 orders
table 架构:
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');
});
}
现在我翻遍了互联网,试图找出问题所在。所有关于这个问题的 post 都是指订单 table 必须创建 BEFORE 具有外键的 table但这对我来说不是问题,因为我的文件顺序正确。
由于increments()
创建了一个无符号整数列,您需要将外键列也定义为无符号整数。
Laravel 6+ 中的默认迁移使用 bigIncrements()
,因此您需要使用 unsignedBigInteger()
方法:
$table->unsignedBigInteger('order_id');
https://laravel.com/docs/6.x/migrations#foreign-key-constraints
对于旧版本 Laravel 中的默认迁移,使用 unsignedInteger()
方法:
$table->unsignedInteger('order_id');
或:
$table->integer('order_id')->unsigned();
https://laravel.com/docs/5.5/migrations#foreign-key-constraints
对于那些标记答案无效的人:
检查 table 的引擎。就我而言,我在 InnoDB 源 table 中引用了 MyISAM table。将参考 table 引擎更改为 InnoDB 后,它成功了!
- 迁移文件的创建方式应首先是父迁移,然后是带有外键的迁移文件。
- 另一个 table 中的外键和主 ID 应该完全相似 属性。如果主 ID 是递增的,则使外键为 integer('xxx_id')->unsigned();
我也遇到了同样的错误。我在 users table 中所做的是,
$table->unsignedInteger('role_id')->default(2);
table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
但是我在创建用户 table 之后创建了角色 table。因此,我在用户 table 文件名日期之前编辑了角色迁移文件名日期。像这样,
2013_01_22_091213_create_roles_table.php
2014_10_12_000000_create_users_table.php
终于成功了。也许有时你会遇到这个问题。所以,我发布了它。
检查迁移顺序。如果您的迁移命令试图在命令 table 之前创建 sell_shipping_labels table,这将与 MySQL 一起发生。它似乎继续创建迁移日期,从最旧到最新。换句话说,它试图引用的 table 上的 order_id 应该存在。
我遇到了同样的问题,我更改了创建迁移日期。
我遇到了同样的问题并解决了将数据库类型设置为 innoDB
的问题
在迁移之前创建的 tables 默认情况下来自遗留系统的 MyISAM 和迁移的是 innoDB
,所以 table 类型的混合是我的问题案例.
Laravel 5.8.3自带
$table->bigIncrements('id');
改为
$table->increments('id');
$table->integer('order_id')->unsigned();
外键必须是 "unsignedBigInteger" 并且会被修复,
像这样:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
我今天遇到了这个问题。我检查了所有建议的解决方案,例如引用键和外键相同的数据类型、数据库引擎中的相同排序规则和 laravel 配置(database.php)、迁移的日期顺序和其他可能的错误,但任何人都是我的解决方案!
我发现的最后一件事是放在迁移中的 onUpdate 和 onDelete 约束。通过删除它们,我的问题解决了!
致所有使用 laravel 5 查看此内容的人。8.x
我通过改变来解决这个问题
这个
$table->unsignedInteger('foreign_id');
至此
$table->unsignedBigInteger('foreign_id');
这是由于使用了 bigIncrements。
您可以改为删除机会 bigIncrements 以增加关系两侧的增量
我今天遇到了同样的问题。我的 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');
希望这有效。
主键和外键应该是相同的数据类型.
如果主键使用无符号big_integer
,外键也应该使用无符号big_integer
。
如果 laravel 5.8 在生成新迁移时默认使用 bigIncrements
(请参阅此 pull request),您应该确保您的 foreign key
也是未签名的 big_integer
否则你会得到错误。
Table users
:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
...
}
Table orders
:
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
...
$table->foreign('user_id')->references('id')->on('users');
}
希望对您有所帮助。
如果问题还没有解决,请尝试一下。
您需要创建最后一个关联的 table.
您应该先创建订单,然后再创建 sell_shipping_labels table
要解决此问题,您应该将类别和用户的迁移文件重命名为餐前迁移文件的日期 table。
[![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');
});
}
大多数情况下,此错误的原因通常是迁移文件的列出顺序或类型转换导致的错误。
始终确保要对其施加外部约束的文件的迁移发生在父迁移之后。
对于后者,请确保它是一个 unsignedBigInteger ,尽管 laravel (<5.4) 的旧版本可以忽略此类型转换错误。
我今天遇到了这个问题。我的 parent table 主键数据类型和 child table 数据类型相同,但错误仍然存在。我发现我的 parent 和 child table 存储引擎不同。我通过从我的 phpmyadmin 制作两个 tables 存储引擎 InnoDB 来解决这个问题。
对于 laravel 6+ 用户,我同意前 2 个答案,它完全取决于 laravel 版本,对于最新版本用户 id
列使用 big integer
。因此,从当前迁移中引用用户 id
,您需要使用 unsignedBigInteger
作为引用键。
下面是 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');
});
在 Laravel 中添加外键的更好方法是使用别名。所以代替:
$table->unsignedBigInteger('user_id'); // foreigh key
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
我们可以简单地这样做:
$table->foreignId('user_id')->constrained();
这对我有用。谢谢!
我用的时候问题解决了
bigInteger('user_id')->无符号();
用简单的代码避免所有这两行代码
这意味着 sell_shipping_labels.order_id
引用 orders
table 上的 id,如下所示
Schema::table('sell_shipping_labels', function (Blueprint $table) {
$table->foreignId('order_id')->constrained('orders');
});
如果您的迁移依赖于父迁移,那么您需要确保先运行父迁移。所以我所做的是:
- 复制当前子迁移的内容
- 使用
php artisan make:migration create_<models>_table
重新创建迁移文件
- 运行
php artisan migrate:fresh
希望有用。
我有一个订单 table 和一个 sell_shipping_labels
将 orders.id
引用为外国人。但是,当我 运行 Laravel 迁移时,我得到了可怕的错误代码:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create tablecheapbooks_test
.#sql-b5b_b2a
(errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter tablesell_shipping_labels
add constraintsell_shipping_labels_order_id_foreign
foreign key (order_id
) referencesorders
(id
))[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create tablecheapbooks_test
.#sql-b5b_b2a
(errno: 150 "Foreign key constraint is incorrectly formed")
这是我的 orders
table 架构:
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');
});
}
现在我翻遍了互联网,试图找出问题所在。所有关于这个问题的 post 都是指订单 table 必须创建 BEFORE 具有外键的 table但这对我来说不是问题,因为我的文件顺序正确。
由于increments()
创建了一个无符号整数列,您需要将外键列也定义为无符号整数。
Laravel 6+ 中的默认迁移使用 bigIncrements()
,因此您需要使用 unsignedBigInteger()
方法:
$table->unsignedBigInteger('order_id');
https://laravel.com/docs/6.x/migrations#foreign-key-constraints
对于旧版本 Laravel 中的默认迁移,使用 unsignedInteger()
方法:
$table->unsignedInteger('order_id');
或:
$table->integer('order_id')->unsigned();
https://laravel.com/docs/5.5/migrations#foreign-key-constraints
对于那些标记答案无效的人:
检查 table 的引擎。就我而言,我在 InnoDB 源 table 中引用了 MyISAM table。将参考 table 引擎更改为 InnoDB 后,它成功了!
- 迁移文件的创建方式应首先是父迁移,然后是带有外键的迁移文件。
- 另一个 table 中的外键和主 ID 应该完全相似 属性。如果主 ID 是递增的,则使外键为 integer('xxx_id')->unsigned();
我也遇到了同样的错误。我在 users table 中所做的是,
$table->unsignedInteger('role_id')->default(2);
table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
但是我在创建用户 table 之后创建了角色 table。因此,我在用户 table 文件名日期之前编辑了角色迁移文件名日期。像这样,
2013_01_22_091213_create_roles_table.php
2014_10_12_000000_create_users_table.php
终于成功了。也许有时你会遇到这个问题。所以,我发布了它。
检查迁移顺序。如果您的迁移命令试图在命令 table 之前创建 sell_shipping_labels table,这将与 MySQL 一起发生。它似乎继续创建迁移日期,从最旧到最新。换句话说,它试图引用的 table 上的 order_id 应该存在。
我遇到了同样的问题,我更改了创建迁移日期。
我遇到了同样的问题并解决了将数据库类型设置为 innoDB
在迁移之前创建的 tables 默认情况下来自遗留系统的 MyISAM 和迁移的是 innoDB
,所以 table 类型的混合是我的问题案例.
Laravel 5.8.3自带
$table->bigIncrements('id');
改为
$table->increments('id');
$table->integer('order_id')->unsigned();
外键必须是 "unsignedBigInteger" 并且会被修复, 像这样:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
我今天遇到了这个问题。我检查了所有建议的解决方案,例如引用键和外键相同的数据类型、数据库引擎中的相同排序规则和 laravel 配置(database.php)、迁移的日期顺序和其他可能的错误,但任何人都是我的解决方案! 我发现的最后一件事是放在迁移中的 onUpdate 和 onDelete 约束。通过删除它们,我的问题解决了!
致所有使用 laravel 5 查看此内容的人。8.x 我通过改变来解决这个问题 这个
$table->unsignedInteger('foreign_id');
至此
$table->unsignedBigInteger('foreign_id');
这是由于使用了 bigIncrements。 您可以改为删除机会 bigIncrements 以增加关系两侧的增量
我今天遇到了同样的问题。我的 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');
希望这有效。
主键和外键应该是相同的数据类型.
如果主键使用无符号big_integer
,外键也应该使用无符号big_integer
。
如果 laravel 5.8 在生成新迁移时默认使用 bigIncrements
(请参阅此 pull request),您应该确保您的 foreign key
也是未签名的 big_integer
否则你会得到错误。
Table users
:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
...
}
Table orders
:
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
...
$table->foreign('user_id')->references('id')->on('users');
}
希望对您有所帮助。
如果问题还没有解决,请尝试一下。 您需要创建最后一个关联的 table.
您应该先创建订单,然后再创建 sell_shipping_labels table
要解决此问题,您应该将类别和用户的迁移文件重命名为餐前迁移文件的日期 table。
[![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');
});
}
大多数情况下,此错误的原因通常是迁移文件的列出顺序或类型转换导致的错误。
始终确保要对其施加外部约束的文件的迁移发生在父迁移之后。 对于后者,请确保它是一个 unsignedBigInteger ,尽管 laravel (<5.4) 的旧版本可以忽略此类型转换错误。
我今天遇到了这个问题。我的 parent table 主键数据类型和 child table 数据类型相同,但错误仍然存在。我发现我的 parent 和 child table 存储引擎不同。我通过从我的 phpmyadmin 制作两个 tables 存储引擎 InnoDB 来解决这个问题。
对于 laravel 6+ 用户,我同意前 2 个答案,它完全取决于 laravel 版本,对于最新版本用户 id
列使用 big integer
。因此,从当前迁移中引用用户 id
,您需要使用 unsignedBigInteger
作为引用键。
下面是 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');
});
在 Laravel 中添加外键的更好方法是使用别名。所以代替:
$table->unsignedBigInteger('user_id'); // foreigh key
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
我们可以简单地这样做:
$table->foreignId('user_id')->constrained();
这对我有用。谢谢!
我用的时候问题解决了 bigInteger('user_id')->无符号();
用简单的代码避免所有这两行代码
这意味着 sell_shipping_labels.order_id
引用 orders
table 上的 id,如下所示
Schema::table('sell_shipping_labels', function (Blueprint $table) {
$table->foreignId('order_id')->constrained('orders');
});
如果您的迁移依赖于父迁移,那么您需要确保先运行父迁移。所以我所做的是:
- 复制当前子迁移的内容
- 使用
php artisan make:migration create_<models>_table
重新创建迁移文件
- 运行
php artisan migrate:fresh
希望有用。