Knex: Pergunta: Atualize os tipos de coluna enum na migração do knex

Criado em 27 set. 2016  ·  10Comentários  ·  Fonte: knex/knex

Stackoverflow

Estou procurando escrever uma string de migração para adicionar uma nova string ao tipo de coluna enum. Estou tentando adicionar gamma à coluna service .

Tentei com este código abaixo. Isso colide porque a tabela e a coluna já existem.

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

Comentários muito úteis

Apenas para quem deseja saber como o código _pode_ parecer no 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 comentários

Resolva isso, há alguma maneira de usar a API alter ?

enums são feitos com restrições de verificação atualmente e .alter() não tem nenhum tratamento especial para eles ...

Um problema é que .alter() não sabe qual é o tipo original da coluna e é por isso que não sabe se deve descartar a restrição de verificação antiga de enum.

Pelo que eu sei, atualmente, é possível alterar os valores enum permitidos apenas com knex.raw eliminando o antigo e criando uma nova restrição de verificação ...

Acho que poderia ser implementado por algum drop old constraint if exist e, em seguida, criar um novo se o tipo alterado da coluna for enum.

Eu adoraria ver esse recurso sendo implementado.

@elhigu Eu escrevi uma consulta de enum personalizada para que eu pudesse usar enums do Postgres, no entanto, há algum debate na comunidade Postgres sobre condições de verificação vs enums

Apenas para quem deseja saber como o código _pode_ parecer no 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 Obrigado pelo exemplo de código de migração. É mesmo o que eu procurava. No entanto, estou tendo um problema. 'myColumnName' está gerando um erro ao migrar. A mensagem diz "coluna 'mycolumnname' does not exist". Observe que o camelCase está faltando. Alguma ideia de como contornar isso?

@ Jordan24 Você pode compartilhar seu 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'
    ])
  );
};

Se eu colocar o columnName entre aspas duplas, recebo um erro de sintaxe porque as aspas simples não são removidas do código bruto.
Acho que posso abandonar a função e escrever o código bruto duas vezes.

@ Jordan24 Sem as aspas, o PostgreSQL dobra todos os identificadores para minúsculas.

Todos codificados, exceto o 'enum' para contorná-lo. Obrigado pela dica @kibertoad!

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

rarkins picture rarkins  ·  3Comentários

sandrocsimas picture sandrocsimas  ·  3Comentários

saurabhghewari picture saurabhghewari  ·  3Comentários

aj0strow picture aj0strow  ·  3Comentários

mtom55 picture mtom55  ·  3Comentários