【问题标题】:Postgres migration error - error: type already existsPostgres 迁移错误 - 错误:类型已存在
【发布时间】:2019-06-06 15:25:14
【问题描述】:
exports.up = async (knex) => {
  await knex.raw(`
    ALTER TABLE accounts.login RENAME COLUMN type TO old_type;
    CREATE TYPE newest_login_type AS ENUM('hidden', 'github', 'twitter', 'google');
    ALTER TABLE accounts.login ADD COLUMN type newest_login_type;
  `);

  const types = await knex('accounts.login').select('old_type', 'user_id');

  await Promise.all(types.map(async ({ user_id, old_type }) => {
    return knex('accounts.login').where('user_id', user_id).update({ type: old_type });
  }));

  await knex.raw(`
    ALTER TABLE accounts.login DROP COLUMN old_type;
  `);
};

exports.down = async (knex) => {
  await knex.raw(`
    ALTER TYPE newest_login_type RENAME TO old_login_type;
    CREATE TYPE newest_login_type AS ENUM('hidden', 'github', 'twitter');
    ALTER TABLE accounts.login ALTER COLUMN type TYPE newest_login_type USING type::text::newest_login_type;
    DROP TYPE old_login_type;
  `);
};

当我migrate 工作时,rollback 工作,然后migrate 再次抛出以下错误:

错误:类型“newest_login_type”已存在

我在这里做错了什么?谢谢

【问题讨论】:

    标签: javascript postgresql knex.js


    【解决方案1】:

    我很惊讶该代码甚至可以如何工作,但您的问题是 up 脚本预计 newest_login_type 不存在并且您的向下脚本不会删除该类型,而只会重命名并重新创建它。

    所以:

    1. 运行起来,newest_login_type 已创建
    2. 跑下来newest_login_type修改
    3. 再次运行失败,因为newest_login_type 已经存在

    ps。这根本不起作用,因为您不应该将多个 SQL 语句传递给单个 knex.raw 调用。许多 DB 驱动程序不支持这一点,包括与 knex 的 postgresql 方言一起使用的 pg 驱动程序。

    【讨论】:

    • 单个knex.raw 调用中的多个语句遍布我们的迁移代码,因此它绝对有效:)
    • 有趣。您使用的是哪个 knex / pg 版本?你有没有为它设置一些特殊的连接参数? (我多年来一直是 knex 维护者,我确信这并不总是可能的)
    • 我可以稍后深入研究以找出答案。我不知道在我的头顶。我解决了我的问题,我的down 需要为枚举创建一个与现状类型等效的类型。 Up可以创建新的。谢谢米凯尔
    • 找到了 :) github.com/brianc/node-postgres/issues/1190 (只要不使用参数绑定就可以工作......就像mysql一样也可以这样做)
    猜你喜欢
    • 2018-07-26
    • 2017-06-18
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 2019-11-17
    • 1970-01-01
    • 2013-02-04
    相关资源
    最近更新 更多