Postgres migration error - error: type already exists

Postgres migration error - error: type already exists

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 再次抛出以下错误:

error: type "newest_login_type" already exists

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

我很惊讶该代码如何工作,但你的问题是 up 脚本期望 newest_login_type 不存在并且你的 down 脚本不会删除该类型,但只会重命名并重新创建它。

所以:

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

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