Knex MySQL Migration "Unhandled rejection Error: Transaction query already complete"

Knex MySQL Migration "Unhandled rejection Error: Transaction query already complete"

我对几乎所有东西都是新手。我尝试使用单个迁移文件在 MySQL 数据库 (20 tables) 中创建所有 tables。

exports.up = function(knex, Promise) {

function createTable1() {
    return knex.schema.createTableIfNotExists('Table1', (t) => {
      t.increments('id').primary();
      t.string('col_1', 48).unique().notNullable();
      t.timestamps(true, true);
    }).catch((e) => console.log(e));
}

function createTable2() {
    return knex.schema.createTableIfNotExists('Table2', (t) => {
      t.increments('id').primary();
      t.string('col_1', 48).unique().notNullable();
      t.integer('someId').unsigned().references('Table1.id')
      t.timestamps(true, true);
    }).catch((e) => console.log(e));
}

function createTable3() {
    return knex.schema.createTableIfNotExists('Table3', (t) => {
      t.increments('id').primary();
      t.string('col_1', 48).unique().notNullable();
      t.integer('someId').unsigned().references('Table1.id')
      t.integer('someOtherId').unsigned().references('Table2.id')
      t.timestamps(true, true);
    }).catch((e) => console.log(e));
}
... //similar functions for all 20 tables

return Promise.all([
    createTable1()
    .then(createTable2())
    .then(createTable3())
    ...
    .then(createTable20())
    .catch((e) => console.log(e.sql))
  ]);
}

exports.down = function(knex, Promise) {

  return knex.schema.dropTable('Table1')
  .then(knex.schema.dropTable('Table2'))
  .then(knex.schema.dropTable('Table3'))
  ...
  .then(knex.schema.dropTable('Table20'))
  .catch((e) => console.log(e.sql))
};

我希望 knex 在一次交易中执行所有 sql 查询

迁移执行但生成以下错误:

Unhandled rejection Error: Transaction query already complete, run with DEBUG=knex:tx for more info

诚然,我对如何正确使用 promises 没有把握,我知道 return Promise.all 块不一定会生成并执行 SQL 中的查询同样的命令,但我应该这样做吗?为每个 table 创建一个单独的迁移文件是否更有意义?

您正在调用承诺链中的函数,而不是将它们链接起来。第一个函数应该被执行,然后与 .then 中的其他函数链接。您似乎也混淆了承诺链和 Promise.all.

的用法

如果您希望按顺序创建每个 table,请删除 Promise.all 并调用函数:

return createTable1()
  .then(createTable2)
  .then(createTable3)
  ...
  .then(createTable20)
  .catch((e) => console.log(e.sql))

如果你想同时创建 N table 个,请像这样使用 Promise.all

return Promise.all([createTable1(), createTable2(), ..., createTable20()])