21

knex で移行を行う方法がまだわかりません。これが私がこれまでに持っているものです。で動作しますupdown、foreign_key_checks = 0 でも FK 制約エラーが発生します。

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

  ]);
};
4

6 に答える 6

15

jedd.ahyoung は正しいです。接続プールを 1 に制限する必要はありません。Promise が並行して実行されないようにチェーンするだけで済みます。

例えば:

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

また、何か不足している可能性がありますが、メンバーテーブルの前にアドレステーブルを作成する場合、外部キーチェックを削除してから元に戻す必要はないようです。

最終的なコードは次のようになります。

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();
    });
  }
};
于 2016-06-02T13:13:11.670 に答える
11

接続プールが原因で機能していないことがわかりました。各移行タスクを実行するために異なる接続が使用されるため、外部キー チェックが適切に設定されませんでした。設定

pool:{
  max:1
}

移行構成ファイルでこれを修正しました。

于 2014-03-26T01:00:18.610 に答える