基本上,我和这个人有同样的问题,减去表前缀。因为我没有表前缀,他的修复不起作用。 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。
我对外键究竟做错了什么?
答案 0 :(得分:78)
我一直有同样的问题。我刚刚在Laravel Schema docs的最底部注意到以下注释:
注意:外键中引用的字段很可能是自动增量,因此自动为无符号整数。请确保使用unsigned()创建外键字段,因为两个字段必须是完全相同的类型,两个表上的引擎必须设置为InnoDB,并且必须在具有外键的表之前创建引用的表
对我来说,只要我设置我的外键字段:
$table->integer('author')->unsigned();
我没有问题。
编辑:此外,请确保已创建外表中的字段,否则可能会失败并出现相同的错误。
答案 1 :(得分:11)
我不是百分之百确定这些是失败的原因,而是几个指针。如果您使用较旧版本的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');
});
希望这有助于/解决您的问题。
答案 2 :(得分:8)
已列出的答案摘要,加上我的:
外键通常需要InnoDb
,因此请设置默认引擎,或明确指定
$table->engine = 'InnoDB';
外键需要引用的表存在。在创建密钥之前,请确保在先前的迁移中创建了引用的表。考虑在单独的迁移中创建密钥以确保。
外键要求数据类型一致。检查引用的字段是否是相同的类型,无论是有符号还是无符号,它的长度是否相同(或更小)。
如果要在手动编码迁移和使用生成器之间切换,请确保检查正在使用的ID类型。 Artisan默认使用 incrementments(),但Jeffrey Way似乎更喜欢整数('id',true)。
答案 3 :(得分:6)
我也遇到了这个问题。
我发现的解决方案是,在另一个表可以引用它之前,需要创建包含正在使用外部id的id的表。基本上,您正在创建一个表并告诉MySQL引用另一个表的主键,但该表尚不存在。
在您的示例中,需要首先创建作者和课程表。
创建表的顺序取决于工匠以及您创建迁移文件的顺序。
我的意见是清空所有表的数据库并更改迁移文件名中的时间戳(或删除它们并以正确的顺序重新创建它们),以便在教程表之前创建作者和课程表
答案 4 :(得分:4)
我收到了同样的错误,因为我忘了在引用的表上将表类型设置为InnoDB:
$table->engine = 'InnoDB';
答案 5 :(得分:3)
在我的情况下,错误与此相同。
错误:[Illuminate \ Database \ QueryException]
SQLSTATE [HY000]:常规错误:1005无法创建表 'nabsh。#sql-5b0_e'(错误号:121)(SQL:alter tableusermeta
add 约束usermeta_uid_foreign外键(uid
)参考 关于删除级联的users
(id
)。
我在这个问题的批准答案中找到了一个很好的提示: ERROR: Error 1005: Can't create table (errno: 121)
提示:如果您尝试使用已在其他位置使用的名称添加约束,您将收到此消息。
在我的情况下,这个错误意味着已尝试添加的约束已存在于某处(但我无法在任何地方看到它们)。
我复制了输出错误查询并在sequel pro中执行它,然后希望我再次看到相同的错误。正如小贴士所说,我将约束名称更改为其他内容然后它没有出现任何错误,因此laravel5 + MySQL55 + CentOS65中的约束名称构建器出现问题。
解决方案:尝试通过在表架构中的foreign方法发送第二个参数来重命名约束。
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');
});
我希望它有所帮助。它适用于我的情况
答案 6 :(得分:1)
在Yii Framework 1.x迁移中也发生了这种情况。原来那个 类似于上面的Laravel解决方案,它可能是由
引起的答案 7 :(得分:1)
使用外键-s 时,请确保您的外键为unsigned
。这对我有用
答案 8 :(得分:0)
最简单的方法是禁用外键检查:
exports.config = {
capabilities: {
'browser' : 'ie',
'browserName': '',
'browser_version' : '11',
'os' : 'Windows',
'os_version' : '7',
'browserstack.user': 'XXX',
'browserstack.key': 'XXX',
'version': 11,
'nativeEvents': false,
'unexpectedAlertBehaviour': 'accept',
'ignoreProtectedModeSettings': true,
'enablePersistentHover': true,
'disable-popup-blocking': true
}
};
答案 9 :(得分:0)
这是我在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');
});
这一切都是为了结论,它对我有用。
答案 10 :(得分:0)
你必须在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();
});
}
答案 11 :(得分:0)
基本上,您会收到此错误,因为迁移命令创建表的顺序与您为表提供的FK参考不匹配。
如果您要创建一个FK,该FK应该引用users表中的id,则users表必须存在。
在您的示例中,需要首先创建作者和课程表。
因此,我通过按顺序创建表(一个接一个)解决了这个问题,在这里我可以成功地将FK引用到现有表。因此,Php Artisan Migration无法决定顺序。
另一种解决方案是,您可以简单地重命名迁移命令提供的表或时间戳。