Knex: 无法添加外键约束

创建于 2014-04-17  ·  11评论  ·  资料来源: knex/knex

使用以下代码运行迁移时,我收到“无法添加外键约束”消息。 有人指出我正确的方向吗?

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) {

};  

最有用的评论

作为对未来阅读本文的人的仅供参考:
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
就是现在
table.integer('UserId',11).unsigned().references('UserId').inTable('User');

所有11条评论

假设您可能正在使用 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 可以创造奇迹,但如果您能在文档中找到类似的常见修复/问题,那就更好了。

无论如何,伟大的工作!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

mishitpatel picture mishitpatel  ·  3评论

nklhrstv picture nklhrstv  ·  3评论

rarkins picture rarkins  ·  3评论

tjwebb picture tjwebb  ·  3评论

lanceschi picture lanceschi  ·  3评论