使用以下代码运行迁移时,我收到“无法添加外键约束”消息。 有人指出我正确的方向吗?
exports.up = function(knex, Promise) {
var defer=Promise.defer();
knex.schema.createTable('User',function(table){
//--Create User Table
table.increments('UserId').primary();
table.string('username');
table.string('email',60);
table.string('password',65);
table.timestamps();
})
.then(function(){
return knex.schema.createTable('Comment',function(table){
//--Create Comment Table
table.increments('CommentId').primary();
table.string('Comment');
table.integer('UserId',11).inTable('User').references('UserId');
});
})
.then(function(){
defer.resolve();
});
return defer.promise;
};
exports.down = function(knex, Promise) {
};
假设您可能正在使用 mysql,您需要指定UserId
是.unsigned()
您也不应该在那里需要延迟,您可以返回knex.schema.createTable
。
exports.up = function(knex, Promise) {
return knex.schema.createTable('User',function (table){
table.increments('UserId').primary();
table.string('username');
table.string('email',60);
table.string('password',65);
table.timestamps();
})
.then(function () {
return knex.schema.createTable('Comment',function(table){
table.increments('CommentId').primary();
table.string('Comment');
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
});
});
};
你几乎永远不需要Promise.defer
。
哇。 你们好棒!! 工作完美。 感谢您的快速响应和更简洁代码的提示:)
你说对了! 您可能会发现将 data/pk 字段和 fk 引用拆分为两个迁移更容易。 另一种方法是您在此处所做的,但请记住,您还需要确保回滚的顺序。
在即将推出的版本中,您将能够链接所有模式调用,并保证它们按顺序运行:
exports.up = function(knex, Promise) {
return knex.schema.createTable('User', function(table){
table.increments('UserId').primary();
table.string('username');
table.string('email',60);
table.string('password',65);
table.timestamps();
}).createTable('Comment',function(table){
table.increments('CommentId').primary();
table.string('Comment');
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
});
};
向下迁移:
exports.down = function(knex, Promise) {
return knex.schema.dropTable('Comment').dropTable('User');
};
作为对未来阅读本文的人的仅供参考:
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
就是现在table.integer('UserId',11).unsigned().references('UserId').inTable('User');
谢谢@蝙蝠侠!
notNullable() 出错。 我的外键始终为空:
前 1:) table.integer('restaurant_id').unsigned().references('id').inTable('Restaurants');
外键(“restaurant_id”)与“餐厅”表中的“id”不匹配。当我尝试使用时,它只是空的:
EX2: ) table.integer('restaurant_id').unsigned().notNullable().references('id').inTable('Restaurants');
这引发了错误(无法添加外键约束)。
如果该外键是一个字符串,但使用一个引用主键('id)的整数,我已经看到这个表单的外键创建工作。 是否因为父级中的主键('id')不是整数类型并且是默认类型?
table.increments('id').primary();
我已经看到外键在它们是字符串类型时起作用,但是在另一个表中对主键('id')进行整数类型引用会引发错误。
当我使用 EX1) 时,一切似乎都可以正常工作,但我的外键不会自动递增,它始终为空。 我也不能使用模型函数手动增加它。 这个问题在某个地方得到解决了吗?
谢谢,
更新:
弄清楚,您只需将整数列添加到单独的行中,然后将其设为外键。
table.integer('restaurant_id').unsigned();
table.integer('location_id').unsigned();
table.foreign('restaurant_id').references('Restaurants.id');
table.foreign('location_id').references('Locations.id');
在文档中可能值得澄清的是,在 MySQL 中定义外键时应该使用 .unsigned() 方法。 我尝试将它与 Objection.js 一起使用,但几乎放弃了,因为我才刚刚开始,乍一看就遇到了错误。 认为这两个框架都是错误的。
认为这两个框架都是错误的。
@Juanpam不需要使用它们。 不过欢迎 PR。 祝你好运 :)
@elhigu我不是有意冒犯任何人! 我确实在使用框架😄。 只是认为对于像我这样的新手来说,这可能是一个常见问题,因为关系是 ORM 和查询构建器中常用的功能。 此外,MySQL 是一种常见的 RDBMS。
我现在不能做 PR,但如果有人感兴趣,我在创建外键时尝试使用 XAMPP MySQL。 事实证明,当使用 .primary() 方法时,创建的字段类型是 INT(11) 无符号的,而当您使用 .integer() 创建引用字段时,结果字段类型是 INT(11) 有符号的,因此外键创建失败。 @tgriesser fix 可以创造奇迹,但如果您能在文档中找到类似的常见修复/问题,那就更好了。
无论如何,伟大的工作!
最有用的评论
作为对未来阅读本文的人的仅供参考:
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
就是现在
table.integer('UserId',11).unsigned().references('UserId').inTable('User');