Comment faire des migrations knex.js?

Je ne suis toujours pas sûr de faire mes migrations avec knex. Voici ce que j'ai jusqu'ici. Il fonctionne en up , mais en down me donne une erreur de contrainte FK même si foreign_key_checks = 0.

 exports.up = function(knex, Promise) { return Promise.all([ knex.raw('SET foreign_key_checks = 0;'), /* CREATE Member table */ knex.schema.createTable('Member', function (table) { table.bigIncrements('id').primary().unsigned(); table.string('email',50); table.string('password'); /* CREATE FKS */ table.bigInteger('ReferralId').unsigned().index(); table.bigInteger('AddressId').unsigned().index().inTable('Address').references('id'); }), /* CREATE Address table */ knex.schema.createTable('Address', function (table) { table.bigIncrements('id').primary().unsigned(); table.index(['city','state','zip']); table.string('city',50).notNullable(); table.string('state',2).notNullable(); table.integer('zip',5).unsigned().notNullable(); }), knex.raw('SET foreign_key_checks = 1;') ]); }; exports.down = function(knex, Promise) { return Promise.all([ knex.raw('SET foreign_key_checks = 0;'), knex.schema.dropTable('Address'), knex.schema.dropTable('Member'), knex.raw('SET foreign_key_checks = 1;') ]); }; 

Il a découvert que cela ne fonctionnait pas en raison de la mise en commun de la connexion. Il utiliserait une connexion différente pour exécuter chaque tâche de migration qui a empêché les contrôles de clés étrangères de ne pas être correctement configurés. réglage

 pool:{ max:1 } 

Dans le fichier de configuration de migration, cela a été corrigé.

Jedd.ahyoung est correct. Vous n'avez pas besoin de limiter votre pool de connexion à 1. Vous devez simplement chaîner vos promesses afin qu'elles ne soient pas exécutées en parallèle.

Par exemple:

 exports.up = function(knex, Promise) { return removeForeignKeyChecks() .then(createMemberTable) .then(createAddressTable) .then(addForeignKeyChecks); function removeForeignKeyChecks() { return knex.raw('SET foreign_key_checks = 0;'); } function addForeignKeyChecks() { return knex.raw('SET foreign_key_checks = 1;'); } function createMemberTable() { return knex.schema.createTable('Member', function (table) { table.bigIncrements('id').primary().unsigned(); table.string('email',50); table.string('password'); /* CREATE FKS */ table.bigInteger('ReferralId').unsigned().index(); table.bigInteger('AddressId').unsigned().index().inTable('Address').references('id'); }); } function createAddressTable() { return knex.schema.createTable('Address', function (table) { table.bigIncrements('id').primary().unsigned(); table.index(['city','state','zip']); table.string('city',50).notNullable(); table.string('state',2).notNullable(); table.integer('zip',5).unsigned().notNullable(); }); } }; 

Aussi, je risque de manquer quelque chose, mais il semble que vous n'aurez pas besoin de supprimer, puis de réintroduire les vérifications de clés étrangères si vous créez la table d'adresses avant la table des membres.

Voici comment apparaitrait le code final:

 exports.up = function(knex, Promise) { return createAddressTable() .then(createMemberTable); function createMemberTable() { return knex.schema.createTable('Member', function (table) { table.bigIncrements('id').primary().unsigned(); table.string('email',50); table.string('password'); /* CREATE FKS */ table.bigInteger('ReferralId').unsigned().index(); table.bigInteger('AddressId').unsigned().index().inTable('Address').references('id'); }); } function createAddressTable() { return knex.schema.createTable('Address', function (table) { table.bigIncrements('id').primary().unsigned(); table.index(['city','state','zip']); table.string('city',50).notNullable(); table.string('state',2).notNullable(); table.integer('zip',5).unsigned().notNullable(); }); } }; 

inTable() doit être placé après les references() :

inTablecolumn.inTable(table)

Définit le table où la colonne de clé étrangère est située après avoir appelé les column.references .

Documentation .

J'ai résolu ce problème en utilisant une transaction

Transation.js

 module.exports = function transaction(fn) { return function _transaction(knex, Promise) { return knex.transaction(function(trx) { return trx .raw('SET foreign_key_checks = 0;') .then(function() { return fn(trx, Promise); }) .finally(function() { return trx.raw('SET foreign_key_checks = 1;'); }); }); }; } 

Fichier de migration

 var transaction = require('../transaction'); function up(trx, Promise) { return trx.schema .createTable('contract', function(table) { table.boolean('active').notNullable(); table.integer('defaultPriority').unsigned().references('priority.id'); table.integer('defaultIssueStatus').unsigned().references('issueStatus.id'); table.integer('owner').notNullable().unsigned().references('user.id'); }) .createTable('user', function (table) { table.increments('id').primary(); table.datetime('createdAt'); table.datetime('updatedAt'); table.string('phoneNumber').notNullable().unique(); table.string('password').notNullable(); table.string('name').notNullable().unique(); table.string('email'); table.string('status'); table.string('roles').defaultTo('user'); table.integer('contract').unsigned().references('contract.id'); }); } function down(trx, Promise) { return trx.schema .dropTable('contract') .dropTable('user'); } exports.up = transaction(up); exports.down = transaction(down);