Knex: Pregunta: Actualice los tipos de columnas de enumeración en la migración de knex

Creado en 27 sept. 2016  ·  10Comentarios  ·  Fuente: knex/knex

Desbordamiento de pila

Estoy buscando escribir una cadena de migración para agregar una nueva cadena al tipo de columna de enumeración. Estoy intentando agregar gamma a la columna service .

Intenté con este código a continuación. Esto choca porque la tabla y la columna ya existen.

const table = 'user_associations'

export function up (knex, Promise) {
  return knex.schema.table(table, function (table) {
    table.enu('service', ['alpha', 'beta', 'gamma']).notNullable()
  })
}

export function down (knex, Promise) {
  return knex.schema.table(table, function (table) {
    table.enu('service', ['alpha', 'beta']).notNullable()
  })
}
PR please

Comentario más útil

Solo para cualquiera que quiera saber cómo se verá el código _podría_ verse en Postgres 9

const formatAlterTableEnumSql = (
  tableName,
  columnName,
  enums,
) => {
  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      "'::text, '"
    )}'::text]));`,
  ].join('\n');
};


exports.up = async function up(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
      'enum3',
    ])
  );
};

exports.down = async function down(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
    ])
  );
};

Todos 10 comentarios

Toca esto, ¿alguna forma de usar la API alter ?

Las enumeraciones se realizan con restricciones de verificación actualmente y .alter() no tiene ningún tratamiento especial para ellas ...

Un problema es que .alter() no sabe cuál es el tipo original de la columna y por eso no sabe si debería eliminar la antigua restricción de verificación de enum.

Hasta donde yo sé, actualmente uno puede cambiar los valores de enumeración permitidos solo con knex.raw eliminando el antiguo y creando una nueva restricción de verificación ...

Creo que podría ser implementado por algunos drop old constraint if exist y luego crear uno nuevo si el tipo alterado de la columna es enum.

Me encantaría ver que se implementara esta función.

@elhigu Escribí una consulta de enumeración personalizada para poder usar las enumeraciones de Postgres, sin embargo, existe cierto debate en la comunidad de Postgres sobre las condiciones de verificación frente a las enumeraciones

Solo para cualquiera que quiera saber cómo se verá el código _podría_ verse en Postgres 9

const formatAlterTableEnumSql = (
  tableName,
  columnName,
  enums,
) => {
  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      "'::text, '"
    )}'::text]));`,
  ].join('\n');
};


exports.up = async function up(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
      'enum3',
    ])
  );
};

exports.down = async function down(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
    ])
  );
};

@holloway Gracias por el ejemplo del código de migración. Justo lo que estaba buscando. Sin embargo, me encuentro con un problema. 'myColumnName' arroja un error al migrar. El mensaje dice "la columna 'mycolumnname' no existe". Observe que falta camelCase. ¿Alguna idea sobre cómo solucionarlo?

@ Jordan24 ¿Puedes compartir tu código?

'use strict';

const formatAlterTableEnumSql = (tableName, columnName, enums) => {

  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      `'::text, '`
    )}'::text]));`
  ].join('\n');
};


exports.up = async function up(knex) {

  await knex.raw(
    formatAlterTableEnumSql('item_messages', 'sentMethod', [
      'Web App', 'Email', 'Text Message', 'Log Conversation'
    ])
  );
};

exports.down = async function down(knex) {

  await knex.raw(
    formatAlterTableEnumSql('item_messages', 'sentMethod', [
      'Web App', 'Email', 'Text Message'
    ])
  );
};

Si envuelvo el columnName entre comillas dobles, aparece un error de sintaxis porque las comillas simples no se eliminan en el código sin formato.
Creo que podría eliminar la función y simplemente escribir el código sin procesar dos veces.

@ Jordan24 Sin las comillas, PostgreSQL dobla todos los identificadores a minúsculas.

Codificó todo excepto la 'enumeración' para evitarlo. ¡Gracias por el consejo @kibertoad!

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

fsebbah picture fsebbah  ·  3Comentarios

saurabhghewari picture saurabhghewari  ·  3Comentarios

nklhrstv picture nklhrstv  ·  3Comentarios

mattgrande picture mattgrande  ·  3Comentarios

npow picture npow  ·  3Comentarios