Knex MySQL Migration «Ошибка необработанного отклонения: запрос транзакции уже выполнен»

0

Я новичок практически во всем. Я попытался использовать один файл миграции для создания всех таблиц в базе данных 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.all не обязательно будет генерировать и выполнять SQL-запросы в том же порядке, но должен ли я это делать? Имеет ли смысл создавать отдельный файл миграции для каждой таблицы?

Теги:
knex.js
innodb

1 ответ

0
Лучший ответ

Вы вызываете функции в цепочке обещаний, а не цепляете их. Первая функция должна быть выполнена, а затем связана с другими функциями в .then. Вы также, кажется, смешиваете обещание цепочки и использование 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()])

Ещё вопросы

Сообщество Overcoder
Наверх
Меню