Knex: Невозможно добавить ограничение внешнего ключа

Созданный на 17 апр. 2014  ·  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');

Спасибо, @batman!

Возникли ошибки с 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();

Я видел, как внешние ключи работают, когда они имеют тип String, но наличие ссылки целочисленного типа на первичный ключ («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');

Возможно, стоит уточнить в документах, что метод .unsigned() следует использовать при определении внешних ключей в MySQL. Я пытался использовать это с Objection.js и почти сдался, потому что я только начинал и получил ошибку только на первый взгляд. Думал, что оба фреймворка глючат.

Думал, что оба фреймворка глючат.

@Juanpam не нужно их использовать. Хотя пиар приветствуется. Удачи :)

@elhigu Я не хотел никого обидеть! Я действительно использую фреймворк 😄. Просто подумал, что для новичка, такого как я, это может быть общей проблемой, поскольку отношения — это функция, обычно используемая в ORM и построителях запросов. Кроме того, MySQL является распространенной СУБД.

Я не могу сделать PR прямо сейчас, но если кому-то интересно, я пытался использовать XAMPP MySQL при создании внешних ключей. Оказывается, при использовании метода .primary() тип созданного поля — INT(11) без знака, а когда вы создаете ссылочное поле с помощью .integer(), результирующий тип поля — INT(11) со знаком, поэтому создание внешнего ключа завершается ошибкой. Исправление @tgriesser творит чудеса, но было бы еще лучше, если бы вы могли найти общие исправления/проблемы, подобные этим, в документации.

В любом случае, отличная работа!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги