Knex: Question : Mettre à jour les types de colonnes enum dans la migration knex

Créé le 27 sept. 2016  ·  10Commentaires  ·  Source: knex/knex

Débordement de pile

Je cherche à écrire une chaîne de migration pour ajouter une nouvelle chaîne au type de colonne enum. J'essaie d'ajouter gamma à la colonne service .

J'ai essayé avec ce code ci-dessous. Cela entre en collision car la table et la colonne existent déjà.

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

Commentaire le plus utile

Juste pour tous ceux qui veulent savoir à quoi le code _pourrait_ ressembler dans 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',
    ])
  );
};

Tous les 10 commentaires

C'est bon, un moyen d'utiliser l'API alter ?

les enums sont actuellement effectués avec des contraintes de vérification et .alter() n'a pas de traitement spécial pour eux...

Un problème est que .alter() ne sait pas quel est le type d'origine de la colonne et c'est pourquoi il ne sait pas s'il doit supprimer l'ancienne contrainte de vérification d'enum.

Pour autant que je sache actuellement, on ne peut modifier les valeurs d'énumération autorisées qu'avec knex.raw en supprimant l'ancienne et en créant une nouvelle contrainte de vérification ...

Je pense que cela pourrait être implémenté par quelque drop old constraint if exist , puis en créer un nouveau si le type modifié de la colonne est enum.

J'aimerais voir cette fonctionnalité être implémentée.

@elhigu J'ai écrit une requête d'énumération personnalisée pour pouvoir utiliser les énumérations Postgres, mais il y a un débat dans la communauté Postgres sur les conditions de vérification par rapport aux énumérations

Juste pour tous ceux qui veulent savoir à quoi le code _pourrait_ ressembler dans 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 Merci pour l'exemple de code de migration. Exactement ce que je cherchais. Je rencontre cependant un problème. 'myColumnName' génère une erreur lors de la migration. Le message dit "la colonne 'mycolumnname' n'existe pas". Notez que le camelCase est maintenant manquant. Des idées sur la façon de contourner cela?

@Jordan24 Pouvez-vous partager votre code ?

'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 j'enveloppe le columnName dans des guillemets doubles, j'obtiens une erreur de syntaxe car les guillemets simples ne sont pas supprimés dans le code brut.
Je pense que je pourrais laisser tomber la fonction et écrire le code brut deux fois.

@ Jordan24 Sans les guillemets, PostgreSQL plie tous les identifiants en minuscules.

Tout codé en dur sauf le « enum » pour le contourner. Merci pour le conseil @kibertoad !

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

hyperh picture hyperh  ·  3Commentaires

zettam picture zettam  ·  3Commentaires

sandrocsimas picture sandrocsimas  ·  3Commentaires

mtom55 picture mtom55  ·  3Commentaires

mattgrande picture mattgrande  ·  3Commentaires