【问题标题】:Do I have to write the reverse operation for migration rollback?我必须为迁移回滚编写反向操作吗?
【发布时间】:2019-09-30 23:57:53
【问题描述】:

我使用 knex.js,它是 PostgreSQL 的优秀查询构建器。我还没有找到任何文档来解释如何以正确的方式进行迁移回滚。

目前,我只是在down 函数中编写反向迁移操作来进行迁移回滚。这是正确的方法吗?

import * as Knex from 'knex';

exports.up = async (knex: Knex): Promise<any> => {
  await knex.schema.raw(`
    ALTER TABLE IF EXISTS "GOOGLE_CHANNEL" 
    ADD COLUMN IF NOT EXISTS google_channel_ad_group_cpc_bid INTEGER NOT NULL DEFAULT 0;
  `);

  await knex.schema.raw(`
    UPDATE "GOOGLE_CHANNEL" as gc
    SET
      google_channel_ad_group_cpc_bid = 7
    FROM "CAMPAIGN_TEMPLATE" as ct
    WHERE ct.campaign_channel_id = gc.campaign_channel_id;
  `);
};

exports.down = async (knex: Knex): Promise<any> => {
  // TODO: migration rollback
  await knex.schema.raw(``);
};

我有两个担心:

  1. 如果up函数中有很多SQL语句,为了回滚迁移,我也必须在down函数中写很多SQL语句。

  2. 为什么knex.js不为我们写逆向操作不做迁移回滚?我的意思是,knex.js 可以拍摄快照或记录数据库的保存点。

【问题讨论】:

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


    【解决方案1】:

    是的,要回滚,您可以使用迁移脚本的down 函数。当您运行 knex migrate:rollback 时,down 函数将运行。 Knex 在数据库中有元表,用于确定哪些迁移已运行或未运行。

    例如:

    exports.up = function (knex, Promise) {
      return knex.schema
        .createTable('role', function (table) {
          table.increments('role_id').primary();
          table.string('title').notNullable().unique();
          table.string('description');
          table.integer('level').notNullable(),
        })
        .createTable('user_account', function (table) {
          table.increments('user_id').primary();
          table.integer('role_id').references('role_id').inTable('role').notNullable();
          table.string('username').notNullable().unique();
          table.string('passwordHashed').notNullable();
          table.string('email', 50).notNullable().unique();
        });
    };
    
    exports.down = function (knex, Promise) {
      return knex.schema
        .dropTable('user_account')
        .dropTable('role');
    };
    

    这里我在 up 函数中创建了两个表。 user_account 有一个外键约束,并与role 表链接,这意味着我必须在down 函数中将user_account 表放在role 表之前。

    在您的情况下,您使用更新语句。在 down 函数中,您必须使用硬编码值(迁移前的旧值)进行新更新,或者确保将旧值存储在历史表中。

    至于你的顾虑:

    1. 是的,如果你添加了很多东西,你也必须添加很多代码来反转你正在做的事情。但是,您可以跳过制作向下脚本,但是您将无法回滚。一些(很多?)选择只前进而不回滚。如果他们必须修复某些问题,他们不会回滚,而是使用修复创建一个新的迁移脚本。

      我建议您在开始时创建向下功能。你可以考虑在合适的时候跳过制作它们。不降低功能的人通常必须在部署到生产环境之前在测试或暂存环境中更彻底地测试他们的迁移。这是为了确保它有效,因为它们毕竟无法回滚。

    2. 我无法真正为这里的 Knex 创作者回答问题。但是,您所描述的潜在解决方案基本上是在迁移完成之前备份数据库。毕竟,迁移不仅仅是更改表的布局等。迁移脚本通常也会添加或删除新行。您可以使用备份方法,但您必须自己进行备份。

      Knex 是一个相当简单的查询构建器。如果您希望为您编写迁移脚本,您可能需要一个成熟的 OR 映射器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-30
      • 1970-01-01
      相关资源
      最近更新 更多