“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键
Posted
技术标签:
【中文标题】“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键【英文标题】:"General error: 1005 Can't create table" Using Laravel Schema Build and Foreign Keys 【发布时间】:2012-08-07 07:38:03 【问题描述】:基本上,我和这个人有同样的问题,减去表前缀。因为我没有表前缀,所以他的修复不起作用。 http://forums.laravel.com/viewtopic.php?id=972
我正在尝试使用 Laravel 的 Schema Builder 构建一个表,如下所示:
Schema::create('lessons', function($table)
$table->increments('id');
$table->string('title')->nullable();
$table->string('summary')->nullable();
$table->timestamps();
);
Schema::create('tutorials', function($table)
$table->increments('id');
$table->integer('author');
$table->integer('lesson');
$table->string('title')->nullable();
$table->string('summary')->nullable();
$table->string('tagline')->nullable();
$table->text('content')->nullable();
$table->text('attachments')->nullable();
$table->timestamps();
);
Schema::table('tutorials', function($table)
$table->foreign('author')->references('id')->on('users');
$table->foreign('lesson')->references('id')->on('lessons');
);
问题是,当我运行此代码时(在 /setup 路由中),我收到以下错误:
SQLSTATE[HY000]: General error: 1005 Can't create table 'tutorials.#sql-2cff_da' (errno: 150)
SQL: ALTER TABLE `tutorials` ADD CONSTRAINT tutorials_author_foreign FOREIGN KEY (`author`) REFERENCES `users` (`id`)
Bindings: array (
)
基于网络上的帖子和关于如何设置 Laravel 的 Eloquent 关系的有限文档,我不确定我做错了什么......
users
已经存在,并且它确实有一个id
字段,即auto_increment
。我也在用正确的关系(belongs_to
和has_many
)设置我的模型,但据我所知,这不是问题——这是数据库设置。 DB 是 InnoDB。
外键到底做错了什么?
【问题讨论】:
【参考方案1】:通过使用:
$table->unsignedInteger('author');
代替:
$table->integer('author');
问题会解决的。
问题是整数生成一个 int(11) 变量,而您需要一个 int(10) 变量。 unsignedInteger 会为你做的。
【讨论】:
【参考方案2】:基本上,您会收到此错误,因为迁移命令创建表的顺序与您为表提供的 FK 引用不匹配。
如果你想创建一个 FK,它应该引用用户表中的 id,那么用户表必须存在。
在您的示例中,需要先创建作者表和课程表。
所以,我通过按这样的顺序(一个一个)创建表来解决这个问题,我可以成功地将 FK 引用到现有表。这样 Php Artisan Migration 就无法决定顺序。
另一种解决方案是,您可以简单地重命名迁移命令提供的表或时间戳。
【讨论】:
【参考方案3】:使用外键-s时,请确保您的外键是unsigned
。这对我有用
【讨论】:
【参考方案4】:已经列出的答案摘要,加上我的:
外键一般需要InnoDb
,所以设置你的默认引擎,或者明确指定
$table->engine = 'InnoDB';
外键需要引用的表存在。在创建密钥之前,请确保在较早的迁移中创建了引用的表。确保在单独的迁移中创建密钥。
外键要求数据类型一致。检查引用的字段是否为同一类型,是否有符号或无符号,长度是否相同(或更少)。
如果您在手动编码迁移和使用生成器之间切换,请确保检查您正在使用的 id 类型。 Artisan 默认使用 increments(),但 Jeffrey Way 似乎更喜欢 integer('id', true)。
【讨论】:
第 4 步已修复,现在 Jeffrey 的生成器中为increments()
。
酷!那是什么时候改变的?有 Github 链接吗?
Check This,之前有一个提交修复了创建,这个拉取请求也修复了数据透视表。【参考方案5】:
你必须在 Laravel 5.4 中给整数一个无符号标志,像这样:
public function up()
Schema::create('posts', function (Blueprint $table)
$table->increments('post_id');
$table->text('title');
$table->text('text');
$table->integer('employee_post_id_number')->unsigned();
$table->foreign('employee_post_id_number')->references
('employee_id_number')->on('employees');
$table->timestamps();
);
【讨论】:
【参考方案6】:我也遇到了同样的问题。我刚刚注意到Laravel Schema docs 最底部的以下注释:
注意:外键中引用的字段很可能是自动递增的,因此会自动成为无符号整数。请确保使用 unsigned() 创建外键字段,因为两个字段必须是完全相同的类型,两个表上的引擎必须设置为 InnoDB,并且引用的表必须在具有外键的表之前创建.
对我来说,只要我这样设置外键字段:
$table->integer('author')->unsigned();
我没问题。
编辑:另外,请确保外表中的字段已经创建,否则这可能会失败并出现同样的错误。
【讨论】:
数据类型也是我的问题,两个表都是 InnoDB。 int() 类型不匹配引发了一般错误 1005,然后是 errno:150。当 table_a 上的两个 PK 都与 table_b 上的 FK 列类型完全匹配时,一切都很好。谢谢! 对于我代码中的类似情况,我不得不添加->nullable()
;在->unsigned();
之后,它工作得很好:)
@ArifulHaque 在这里使用 ->nullable() 破坏了外键的目的。只要 ->unsigned() 就足够了。
就我而言,问题是我的外键上没有 ->unsigned()
您必须始终使用->unsigned()
,如果您的 onDelete 操作设置为“设置 null”->onDelete('set null')
,请添加 ->nullable()
【参考方案7】:
这在 Yii Framework 1.x 迁移中也发生在我身上。原来是 与上面的 Laravel 解决方案类似,它可能是由一个
表名拼写错误(或尚不存在) 列名拼写错误(或尚不存在) 在不同表中使用同一数据库中的重复外键名称【讨论】:
【参考方案8】:这是我在 Laravel 5 中所做的:
// CREATING TABLE
Schema::create('your_table_name', function (Blueprint $table)
$table->engine = 'InnoDB';
$table->increments('id'); // index field example sample
$table->string('field2'); // some varchar/string field sample
$table->integer('field3'); // some integer field sample
$table->integer('field_some_table_id')->unsigned; //for field that contains foreign key constraint
);
// FOREIGN KEY CONSTRAINT
Schema::table('stock', function ($table)
$table->foreign('field_some_table_id')->references('id')->on('some_table')->onDelete('cascade')->onUpdate('cascade');
);
这就是结论的全部内容,它对我有用。
【讨论】:
【参考方案9】:最简单的方法是禁用外键检查:
DB::statement('set foreign_key_checks=0');
Schema::table( ... );
DB::statement('set foreign_key_checks=1');
【讨论】:
【参考方案10】:Laravel5、mysql55、CentOS65
在我的情况下,错误与此相同。
错误:[Illuminate\Database\QueryException] SQLSTATE[HY000]:一般错误:1005 无法创建表 'nabsh.#sql-5b0_e' (errno: 121) (SQL: alter table
usermeta
add 约束 usermeta_uid_foreign 外键 (uid
) 参考users
(id
) 删除级联)。
我在这个问题的已批准答案中找到了一个很好的提示: ERROR: Error 1005: Can't create table (errno: 121)
提示:如果您尝试添加名称已在其他地方使用过的约束,您将收到此消息。
在我的情况下,此错误意味着已尝试添加的约束已存在于某处(但我无法在任何地方看到它们)。
我复制了输出错误查询并在 sequel pro 中执行它,然后希望我再次看到相同的错误。正如提示所说,我将约束名称更改为其他名称,然后它没有任何错误影响,因此 laravel5 + MySQL55 + CentOS65 中的约束名称生成器存在问题。
解决方案:尝试通过在表模式的外部方法中发送第二个参数来重命名约束。
Schema::table('tutorials', function($table)
$table->foreign('author')->references('id')->on('users');
$table->foreign('lesson')->references('id')->on('lessons');
);
到 ->
Schema::table('tutorials', function($table)
$table->foreign('author', 'fk_tutorials_author')->references('id')->on('users');
$table->foreign('lesson', 'fk_tutorials_lesson')->references('id')->on('lessons');
);
我希望它有所帮助。它适用于我的情况
【讨论】:
【参考方案11】:我也遇到过这个问题。
我找到的解决方案是,在另一个表可以引用它之前,需要创建包含正在使用的外部 id 的 id 的表。基本上,您正在创建一个表并告诉 MySQL 引用另一个表的主键,但该表还不存在。
在您的示例中,需要先创建作者表和课程表。
创建表的顺序取决于工匠和您创建迁移文件的顺序。
我的意见是清空所有表的数据库并更改迁移文件名中的时间戳(或删除它们并以正确的顺序重新创建它们),以便在创建教程表之前创建作者表和课程表.
【讨论】:
【参考方案12】:我收到了同样的错误,因为我忘记在引用的表上将表类型设置为 InnoDB:
$table->engine = 'InnoDB';
【讨论】:
这解决了我的错误。不幸的是,我的引用表已经创建,所以我必须在迁移中进行手动更新: DB::statement('ALTER TABLE my_table ENGINE = InnoDB');【参考方案13】:我不是 100% 确定这些是否是失败的原因,但有几个指针。如果您使用旧版本的 mySQL 作为数据库,则默认表实现是不支持外键限制的 myISAM。由于您的脚本在外键分配上失败,您最好在 Schema 的 create 方法中使用此语法明确声明您希望 INNODB 作为引擎。
Schema::create('lessons', function($table)
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('title')->nullable();
$table->string('summary')->nullable();
$table->timestamps();
);
这有望缓解您遇到的问题。
此外,虽然您可以事后声明外键,但我会在初始架构中创建外键,因为我可以轻松检查以确保我拥有正确的数据库引擎集。
Schema::create('tutorials', function($table)
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('author');
$table->integer('lesson');
$table->string('title')->nullable();
$table->string('summary')->nullable();
$table->string('tagline')->nullable();
$table->text('content')->nullable();
$table->text('attachments')->nullable();
$table->timestamps();
$table->foreign('author')->references('id')->on('users');
$table->foreign('lesson')->references('id')->on('lessons');
);
希望这有助于/解决您的问题。
【讨论】:
在改组一些东西之后,我仍然得到一些关于外键约束的奇怪错误。奇怪的是——它确实工作,尽管有错误。事实证明,我在上面发布的错误是user.id
字段是int(10) unsigned
的结果,而外键是int(11)
。不过感谢您的建议:)
没有问题 :) 使用上述架构时是否还会出现错误?或者当您输入数据时?
就在我创建架构的时候。据我所知,插入数据非常有效。
嘿@AndrewM,非常感谢您的跟进。遇到了完全相同的问题。以上是关于“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 laravel 迁移错误“一般错误:1005 无法创建表”
一般错误:1005 无法创建表 errno:150“外键约束格式不正确”)
SQLSTATE[HY000]:一般错误:1005 无法创建表 Laravel 8
SQLSTATE [HY000]:一般错误:1005 无法创建表`Data`.`company eligibilities`(errno:150“外键约束形成错误”)