Knex: Fremdschlüsselbeschränkung kann nicht hinzugefügt werden

Erstellt am 17. Apr. 2014  ·  11Kommentare  ·  Quelle: knex/knex

Beim Ausführen einer Migration mit dem folgenden Code erhalte ich die Meldung „Fremdschlüsselbeschränkung kann nicht hinzugefügt werden“. Jemand weist mich in die richtige Richtung?

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

};  

Hilfreichster Kommentar

Als FYI für zukünftige Leute, die dies lesen:
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
ist jetzt
table.integer('UserId',11).unsigned().references('UserId').inTable('User');

Alle 11 Kommentare

Angenommen, Sie verwenden mysql, müssen Sie angeben, dass UserId .unsigned() ist

Sie sollten diese Verzögerung dort auch nicht benötigen, Sie können einfach die knex.schema.createTable zurückgeben.

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

Sie werden fast nie Promise.defer brauchen.

Beeindruckend. Ihr Jungs ROCKT!! Hat perfekt funktioniert. Vielen Dank für die schnelle Antwort und die Tipps zum saubereren Code :)

Du hast es! Möglicherweise finden Sie es einfacher, data/pk-Felder und fk-Referenzen in zwei Migrationen aufzuteilen. Die Alternative ist das, was Sie hier getan haben, aber denken Sie daran, dass Sie dann auch bei den Rollbacks für Ordnung sorgen müssen.

In der kommenden Version können Sie alle Schemaaufrufe verketten und sie werden garantiert nacheinander ausgeführt:

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

nach unten migrieren:

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

Als FYI für zukünftige Leute, die dies lesen:
table.integer('UserId',11).unsigned().inTable('User').references('UserId');
ist jetzt
table.integer('UserId',11).unsigned().references('UserId').inTable('User');

Danke @Batman!

Fehler mit notNullable(). Meine Fremdschlüssel sind immer null:
Beispiel 1:) table.integer('restaurant_id').unsigned().references('id').inTable('Restaurants');
Der Fremdschlüssel ('restaurant_id") stimmt nicht mit der 'id' in der Tabelle 'Restaurants' überein. Er ist einfach null, als ich versuchte, Folgendes zu verwenden:
Beispiel 2: ) table.integer('restaurant_id').unsigned().notNullable().references('id').inTable('Restaurants');
was einen Fehler auslöste (Fremdschlüsselbeschränkungen können nicht hinzugefügt werden).

Ich habe gesehen, wie die Fremdschlüsselerstellung dieses Formulars funktioniert, wenn dieser Fremdschlüssel eine Zeichenfolge ist, aber mit einer Ganzzahl, die auf den Primärschlüssel ('id) verweist. Liegt es daran, dass der Primärschlüssel ('id') im übergeordneten Element nicht vom Typ Integer ist und von einem Standardtyp ist?
table.increments('id').primary();

Ich habe gesehen, dass Fremdschlüssel funktionieren, wenn sie vom Typ String sind, aber eine ganzzahlige Referenz auf den Primärschlüssel ('id') in einer anderen Tabelle löst einen Fehler aus.

Wenn ich EX1 verwende, scheint alles zu funktionieren, aber mein Fremdschlüssel wird nicht automatisch erhöht, er ist einfach die ganze Zeit null. Ich kann es auch nicht manuell mit einer Modellfunktion erhöhen. Wurde dieses Problem irgendwo gelöst?

Danke,

aktualisieren:
Finden Sie es heraus, Sie müssen die Integer-Spalte einfach in einer separaten Zeile hinzufügen, von wo aus Sie sie zu einem Fremdschlüssel machen.

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

Es kann sich lohnen, in den Dokumenten klarzustellen, dass die Methode .unsigned() verwendet werden sollte, wenn Fremdschlüssel in MySQL definiert werden. Ich habe versucht, dies mit Objection.js zu verwenden, und fast aufgegeben, weil ich gerade erst angefangen habe und nur auf den ersten Blick einen Fehler bekommen habe. Dachte, beide Frameworks seien fehlerhaft.

Dachte, beide Frameworks seien fehlerhaft.

@Juanpam keine Notwendigkeit, sie zu verwenden. PRs sind aber willkommen. Viel Glück :)

@elhigu Ich wollte niemanden beleidigen! Ich verwende tatsächlich das Framework 😄. Ich dachte nur, dass es für einen Neuling wie mich ein häufiges Problem sein könnte, da Relationen eine Funktion sind, die häufig in ORMs und Query Buildern verwendet wird. Außerdem ist MySQL ein gängiges RDBMS.

Ich kann gerade keine PR machen, aber falls es jemanden interessiert, ich habe versucht, XAMPP MySQL zu verwenden, während ich die Fremdschlüssel erstellte. Es stellt sich heraus, dass bei Verwendung der Methode .primary() der erstellte Feldtyp INT(11) ohne Vorzeichen ist und wenn Sie das Referenzfeld mit .integer() erstellen, der resultierende Feldtyp INT(11) mit Vorzeichen ist, sodass die Fremdschlüsselerstellung fehlschlägt. @tgriesser Fix wirkt Wunder, aber es wäre noch besser, wenn Sie häufige Fixes/Probleme wie diese in den Dokumenten finden könnten.

Jedenfalls tolle Arbeit!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen