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