首页 > 解决方案 > 使用 Knex + postgres 在迁移中更改枚举类型

问题描述

我需要为 Enum 类型再添加一个值。迁移成功完成,但我在数据库中看不到任何结果。枚举prod_status内部仍然有旧值。

我正在使用此代码进行迁移。

exports.up = async function(knex) {
  return knex.schema.alterTable('products', (table) => {
    table.enu('status', ['hidden', 'published', 'reserved', 'sold', 'deleted', 'not-visible'], { useNative: true, enumName: 'prod_status' }).defaultTo('hidden').notNullable().index().alter();
  }).toSQL();
};

exports.down = async function(knex) {
  return knex.schema.alterTable('products', (table) => {
    table.enum('status', ['hidden', 'published', 'reserved', 'sold', 'deleted'], { useNative: true, enumName: 'prod_status' }).defaultTo('hidden').notNullable().index().alter();
  }).toSQL();
};

我还尝试了类似问题#1#2的其他变体,但出现错误。

寻求您的帮助和/或建议。

标签: databasepostgresqlmigrationknex.js

解决方案


Mikael Lepistö 建议使用.raw它,这确实是解决它的唯一可能方法。我的工作解决方案:

exports.up = async function(knex) {
  return knex.raw(`
    CREATE TYPE prod_status_temp AS ENUM ('hidden', 'published', 'reserved', 'sold', 'deleted', 'not-visible');
    ALTER TABLE products
      ALTER COLUMN status DROP DEFAULT,
      ALTER COLUMN status TYPE prod_status_temp USING status::text::prod_status_temp;
    DROP TYPE IF EXISTS prod_status;
    ALTER TYPE prod_status_temp RENAME TO prod_status;
  `);
};

exports.down = async function(knex) {
  return knex.raw(`
    CREATE TYPE prod_status_temp AS ENUM ('hidden', 'published', 'reserved', 'sold', 'deleted');
    ALTER TABLE products
      ALTER COLUMN status DROP DEFAULT,
      ALTER COLUMN status TYPE prod_status_temp USING status::text::prod_status_temp;
    DROP TYPE IF EXISTS prod_status;
    ALTER TYPE prod_status_temp RENAME TO prod_status;
  `);
};

希望它对将来的人有所帮助。


推荐阅读