【问题标题】:Knex MySQL Migration "Unhandled rejection Error: Transaction query already complete"Knex MySQL 迁移“未处理的拒绝错误:事务查询已完成”
【发布时间】:2017-12-12 10:08:17
【问题描述】:

我对几乎所有事情都很陌生。我尝试使用单个迁移文件在 MySQL 数据库中创建所有表(20 个表)。

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 查询

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

未处理的拒绝错误:事务查询已完成,运行 使用 DEBUG=knex:tx 了解更多信息

诚然,我没有牢牢掌握如何正确使用 Promise,并且我知道 return Promise.all 块不一定会以相同的顺序生成和执行 SQL 查询,但我应该这样做吗?为每个表创建单独的迁移文件是否更有意义?

【问题讨论】:

  • > 为每个表创建单独的迁移文件是否更有意义?我认为这样做更常见

标签: javascript mysql node.js innodb knex.js


【解决方案1】:

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

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

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

如果您想同时创建 N 个表,请使用 Promise.all,如下所示:

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

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2018-11-11
    • 1970-01-01
    • 2023-03-30
    • 2022-09-23
    • 2017-06-08
    相关资源
    最近更新 更多