Knex.js Миграции копируют существующие данные в другую таблицу
Можно ли с помощью миграции Knex.js копировать данные из одной таблицы в другую?
Вариант использования следующий: у меня есть таблица A, которую я хочу разделить на две новые таблицы B и C. В идеале я бы перебрал строки в A, чтобы создать соответствующие строки в B и C и заполнить их правильная информация.
Можно ли это сделать внутри файла миграции? Если исходить из этого вопроса, я считаю, что этот способ миграции в Node.JS довольно сложен (например, по сравнению с ActiveRecord). Есть ли лучший, более управляемый способ сделать такие миграции? Или это отраслевой стандарт?
2 ответа
Нет ничего особенного в объекте построителя запросов, переданном вашему up
а также down
функции внутри файла миграции. Вы можете использовать его так же, как и любой другой экземпляр построителя запросов в своем приложении, то есть запускать любые запросы, которые вы хотите в рамках миграции.
Вот очень простой пример. Учитывая, что у вас есть таблица с именем account с 4 полями, 1 из которых вы хотите разделить на таблицу:
// Starting promise chain with Promise.resolve() for readability only
exports.up = function(knex, Promise) {
return Promise.resolve()
.then(() => knex.schema.createTable('table_b', t => {
t.string('col_a')
t.string('col_b')
}))
.then(() => knex.schema.createTable('table_c', t => {
t.string('col_c')
t.string('col_d')
}))
.then(() => knex('table_a').select('col_a', 'col_b'))
.then((rows) => knex('table_b').insert(rows))
.then(() => knex('table_a').select('col_c', 'col_d'))
.then((rows) => knex('table_c').insert(rows))
.then(() => knex.schema.dropTableIfExists('table_a'))
};
exports.down = function(knex, Promise) {
return Promise.resolve()
.then(() => knex.schema.createTable('table_a', t => {
t.string('col_a')
t.string('col_b')
t.string('col_c')
t.string('col_d')
}))
.then(() => knex('table_b').select('col_a', 'col_b'))
.then((rows) => knex('table_a').insert(rows))
.then(() => knex('table_c').select('col_c', 'col_d'))
.then((rows) => knex('table_a').insert(rows))
.then(() => knex.schema.dropTableIfExists('table_b'))
.then(() => knex.schema.dropTableIfExists('table_c'))
};
В этом случае вы также можете просто сохранить table_a
и вместо создания третьей таблицы просто отбросьте два столбца и переименуйте таблицу. Имейте в виду, однако, что такое разделение вашей таблицы станет грязным, если она уже имеет отношения к другим таблицам в БД.
Насколько я понимаю, миграция имеет дело только с выполнением операций CRUD в таблицах.
knex позволяет вам вызывать функцию после завершения миграции:
`knex.migrate.latest()
.then(function() {
return knex.seed.run();
})
.then(function() {
// migrations are finished
});`
Таким образом, вы можете добавить свой код в исходный файл или просто как функцию, как показано на рисунке.
Обратите внимание, что эта функция вызывается только после завершения миграции, что означает, что ваша таблица A все еще должна присутствовать (не может быть удалена).
Вот соответствующая документация