Knex.js 迁移将现有数据复制到其他 table
Knex.js Migrations copy existing data to other table
是否可以通过 Knex.js 迁移将数据从一个 table 复制到另一个
?
用例如下:
我有一个 table A,我想将其拆分为两个新的 tables B 和 C。理想情况下,我会遍历 A 中的行以在 B 和 C 中创建适当的行并填充它们使用正确的信息。
这可以在迁移文件中完成吗?从这个问题来看,我觉得这种在 Node.JS 中进行迁移的方式非常复杂(例如与 ActiveRecord 相比)。有没有更好、更易于管理的方式来进行此类迁移?或者这是行业标准?
我的理解是迁移只涉及在 table 秒内执行 CRUD 操作。
knex 允许您在迁移完成后调用函数:
`knex.migrate.latest()
.then(function() {
return knex.seed.run();
})
.then(function() {
// migrations are finished
});`
因此,您可以将代码添加到种子文件中,也可以仅作为函数添加,如图所示。
请注意,此函数仅在迁移完成后调用,这意味着您的 table A 仍然必须存在(无法删除)。
这是相关的 documentation
传递给迁移文件中的 up
和 down
函数的查询构建器对象没有什么特别之处。您可以像在您的应用程序中使用查询生成器的任何其他实例一样使用它,即 运行 您希望作为迁移一部分的任何查询。
这是一个非常简单的例子。假设您有一个名为 table 的帐户,其中包含 4 个字段,您希望将其中 1 个单独拆分为 table:
// 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
而不是创建第三个 table,只需删除两列并重命名 table。但是请注意,如果它已经与数据库中的其他 table 有关系,那么像这样拆分您的 table 会变得混乱。
是否可以通过 Knex.js 迁移将数据从一个 table 复制到另一个
?用例如下: 我有一个 table A,我想将其拆分为两个新的 tables B 和 C。理想情况下,我会遍历 A 中的行以在 B 和 C 中创建适当的行并填充它们使用正确的信息。
这可以在迁移文件中完成吗?从这个问题来看,我觉得这种在 Node.JS 中进行迁移的方式非常复杂(例如与 ActiveRecord 相比)。有没有更好、更易于管理的方式来进行此类迁移?或者这是行业标准?
我的理解是迁移只涉及在 table 秒内执行 CRUD 操作。
knex 允许您在迁移完成后调用函数:
`knex.migrate.latest()
.then(function() {
return knex.seed.run();
})
.then(function() {
// migrations are finished
});`
因此,您可以将代码添加到种子文件中,也可以仅作为函数添加,如图所示。
请注意,此函数仅在迁移完成后调用,这意味着您的 table A 仍然必须存在(无法删除)。
这是相关的 documentation
传递给迁移文件中的 up
和 down
函数的查询构建器对象没有什么特别之处。您可以像在您的应用程序中使用查询生成器的任何其他实例一样使用它,即 运行 您希望作为迁移一部分的任何查询。
这是一个非常简单的例子。假设您有一个名为 table 的帐户,其中包含 4 个字段,您希望将其中 1 个单独拆分为 table:
// 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
而不是创建第三个 table,只需删除两列并重命名 table。但是请注意,如果它已经与数据库中的其他 table 有关系,那么像这样拆分您的 table 会变得混乱。