【问题标题】:Knex.js Migrations copy existing data to other tableKnex.js 迁移将现有数据复制到其他表
【发布时间】:2017-12-21 23:58:51
【问题描述】:

是否可以通过 Knex.js 迁移将数据从一个表复制到另一个表?

用例如下: 我有一个表 A,我想将其拆分为两个新表 B 和 C。理想情况下,我会遍历 A 中的行以在 B 和 C 中创建适当的行并用正确的信息填充它们。

这可以在迁移文件中完成吗? Aport from this question,我觉得在 Node.JS 中进行迁移的这种方式非常复杂(例如,与 ActiveRecord 相比)。有没有更好、更管理的方法来进行此类迁移?还是这是行业标准?

【问题讨论】:

    标签: node.js postgresql database-migration knex.js


    【解决方案1】:

    在迁移文件中传递给updown 函数的查询构建器对象没有什么特别之处。您可以像在应用程序中使用任何其他查询构建器实例一样使用它,即在迁移过程中运行您想要的任何查询。

    这是一个非常简单的例子。假设您有一个名为 accounts 的表,其中包含 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,而不是创建第三个表,只需删除两列并重命名该表。但是请注意,如果它已经与数据库中的其他表有关系,那么像这样拆分您的表会变得混乱。

    【讨论】:

      【解决方案2】:

      我的理解是迁移只涉及在表中执行 CRUD 操作。

      knex 允许您在迁移完成后调用函数:

      `knex.migrate.latest()
      .then(function() {
        return knex.seed.run();
      })
      .then(function() {
        // migrations are finished
      });` 
      

      因此,您可以将代码添加到种子文件中,也可以简单地添加为如图所示的函数。
      请注意,此函数仅在迁移完成后调用,这意味着您的表 A 仍然必须存在(无法删除)。
      这是相关的documentation

      【讨论】:

      • 所以这意味着我需要一个额外的脚本来运行这个特定的迁移?因为这种方法的挑战在于数据操作与迁移本身相关联,而不仅仅是“最新”迁移。这是在 Node.JS + Knex 中做到这一点的唯一方法吗?
      • 恐怕我没有足够的资格回答这个问题。如果您只是在寻找一种使用 Active Record 模式保存数据的方法,您应该尝试 bookshelf.js。它是一个建立在 knex.js 之上的 ORM。 Knex 只是一个查询构建器。
      • 我已经在使用 Bookshelf.JS,但我的问题确实与更改数据库结构有关,而不是从数据库中保存/获取数据。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多