Knex: Impossible d'ajouter une contrainte de clé étrangère

Créé le 17 avr. 2014  ·  11Commentaires  ·  Source: knex/knex

Lors de l'exécution d'une migration avec le code ci-dessous, je reçois un message "Impossible d'ajouter une contrainte de clé étrangère". Quelqu'un m'a pointé dans la bonne direction ?

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

};  

Commentaire le plus utile

En guise d'information pour les futurs lecteurs qui liront ceci :
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
est maintenant
table.integer('UserId',11).unsigned().references('UserId').inTable('User');

Tous les 11 commentaires

En supposant que vous utilisez mysql, vous devez spécifier que le UserId est .unsigned()

Vous ne devriez pas non plus avoir besoin de ce délai, vous pouvez simplement retourner le 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');
    });     
  });
};

Vous n'aurez presque jamais besoin Promise.defer .

Wow. Vous êtes top les gars!! A parfaitement fonctionné. Merci pour la réponse rapide et les conseils sur le code plus propre :)

Tu l'as eu! Vous trouverez peut-être plus facile de diviser simplement les champs data/pk et les références fk en deux migrations. L'alternative est ce que vous avez fait ici, mais gardez à l'esprit que vous devez également assurer l'ordre des restaurations.

Dans la version à venir, vous pourrez enchaîner tous les appels de schéma et ils seront assurés de s'exécuter dans l'ordre :

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');  
  });
};

migration vers le bas :

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('Comment').dropTable('User');
};

En guise d'information pour les futurs lecteurs qui liront ceci :
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
est maintenant
table.integer('UserId',11).unsigned().references('UserId').inTable('User');

Merci @batman !

Avoir des erreurs avec notNullable(). Mes clés étrangères sont toujours nulles :
EX 1 :) table.integer('restaurant_id').unsigned().references('id').inTable('Restaurants');
La clé étrangère ('restaurant_id") ne correspond pas à 'id' dans la table 'Restaurants'. Elle est simplement nulle, lorsque j'ai tenté d'utiliser :
EX2 : ) table.integer('restaurant_id').unsigned().notNullable().references('id').inTable('Restaurants');
qui a lancé une erreur (impossible d'ajouter des contraintes de clé étrangère).

J'ai vu la création de clé étrangère de ce formulaire fonctionner si cette clé étrangère est une chaîne, mais avec un entier faisant référence à la clé primaire ('id). Est-ce parce que la clé primaire ('id') dans le parent n'est pas de type entier et est d'un type par défaut ?
table.increments('id').primary();

J'ai vu des clés étrangères fonctionner lorsqu'elles sont de type String, mais le fait d'avoir une référence de type entier à la clé primaire ("id") dans une autre table génère une erreur.

Lorsque j'utilise EX1) Tout semble fonctionner, mais ma clé étrangère ne s'incrémente pas automatiquement, elle est simplement nulle tout le temps. Je ne peux pas non plus l'incrémenter manuellement à l'aide d'une fonction de modèle. Ce problème a-t-il été résolu quelque part ?

Merci,

mettre à jour:
Comprenez-le, il vous suffit d'ajouter la colonne entière sur une ligne distincte de l'endroit où vous en faites une clé étrangère.

table.integer('restaurant_id').unsigned();
          table.integer('location_id').unsigned();
          table.foreign('restaurant_id').references('Restaurants.id');
          table.foreign('location_id').references('Locations.id');

Il peut être utile de préciser dans la documentation que la méthode .unsigned() doit être utilisée lors de la définition des clés étrangères dans MySQL. J'ai essayé de l'utiliser avec Objection.js et j'ai presque abandonné parce que je ne faisais que commencer et j'ai eu une erreur à première vue. Je pensais que les deux cadres étaient bogués.

Je pensais que les deux cadres étaient bogués.

@Juanpam pas besoin de les utiliser. Les relations publiques sont cependant les bienvenues. Bonne chance :)

@elhigu Je ne voulais offenser personne ! J'utilise effectivement le framework 😄. Je pensais juste que pour un nouveau venu, comme moi, cela pourrait être un problème courant puisque les relations sont une fonctionnalité couramment utilisée dans les ORM et les constructeurs de requêtes. De plus, MySQL est un SGBDR courant.

Je ne peux pas faire de relations publiques pour le moment, mais si quelqu'un est intéressé, j'essayais d'utiliser XAMPP MySQL lors de la création des clés étrangères. Il s'avère que lors de l'utilisation de la méthode .primary(), le type de champ créé est INT(11) non signé et lorsque vous créez le champ de référence à l'aide de .integer(), le type de champ résultant est INT(11) signé, de sorte que la création de la clé étrangère échoue. @tgriesser fix fonctionne à merveille, mais ce serait encore mieux si vous pouviez trouver des correctifs/problèmes courants comme ceux-ci dans la documentation.

Quoi qu'il en soit, excellent travail!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

zettam picture zettam  ·  3Commentaires

legomind picture legomind  ·  3Commentaires

rarkins picture rarkins  ·  3Commentaires

sandrocsimas picture sandrocsimas  ·  3Commentaires

fsebbah picture fsebbah  ·  3Commentaires