Search code examples
databasepostgresqlmigrationknex.js

Alter enum type in migration using Knex + postgres


I need to add one more value to Enum type. Migration successfully finished but I don't see any result in database. Enum prod_status still has old values inside.

I'm using this code to make a migration.

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();
};

I have also tried other variants from similar quesitons #1 an #2 but getting errors.

Looking for your help and/or adnivces.


Solution

  • Mikael Lepistö proposed to use .raw and it was really only possible way to solve it. My working solution:

    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;
      `);
    };
    

    Hope it helps somebody in future.