Knex: Frage: Aufzählungsspaltentypen bei der Knex-Migration aktualisieren

Erstellt am 27. Sept. 2016  ·  10Kommentare  ·  Quelle: knex/knex

Paketüberfluss

Ich möchte eine Migrationszeichenfolge schreiben, um dem Aufzählungsspaltentyp eine neue Zeichenfolge hinzuzufügen. Ich versuche, gamma zur Spalte service hinzuzufügen.

Ich habe es mit diesem Code unten versucht. Dies kollidiert, weil die Tabelle und die Spalte bereits vorhanden sind.

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

Hilfreichster Kommentar

Nur für alle, die wissen wollen, wie der Code _might_ in Postgres 9 aussieht

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',
    ])
  );
};

Alle 10 Kommentare

Wie kann man die alter API verwenden?

Aufzählungen werden derzeit mit Prüfbeschränkungen erstellt und .alter() hat keine spezielle Behandlung für sie ...

Ein Problem ist, dass .alter() den ursprünglichen Typ der Spalte nicht kennt und daher nicht weiß, ob es die alte Überprüfungsbeschränkung von enum löschen soll.

Soweit ich weiß, kann man die erlaubten Enum-Werte derzeit nur mit knex.raw ändern, indem man alte ablegt und neue Check-Constraints erstellt...

Ich denke, es könnte von einigen drop old constraint if exist implementiert werden und dann eine neue erstellen, wenn der geänderte Typ der Spalte enum ist.

Ich würde mich freuen, wenn diese Funktion implementiert wird.

@elhigu Ich habe eine benutzerdefinierte Enum-Abfrage geschrieben, damit ich Postgres-Enums verwenden kann, aber in der Postgres-Community gibt es einige Diskussionen über Prüfbedingungen vs

Nur für alle, die wissen wollen, wie der Code _might_ in Postgres 9 aussieht

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 Danke für das Migrationscodebeispiel. Genau das, was ich gesucht habe. Ich stoße jedoch auf ein Problem. 'myColumnName' gibt beim Migrieren einen Fehler aus. Die Meldung sagt "Spalte 'mycolumnname' existiert nicht". Beachten Sie, dass das camelCase jetzt fehlt. Irgendwelche Ideen, wie man das umgehen kann?

@Jordan24 Kannst du deinen Code teilen?

'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'
    ])
  );
};

Wenn ich den Spaltennamen in doppelte Anführungszeichen einschließe, erhalte ich einen Syntaxfehler, da die einfachen Anführungszeichen nicht im Rohcode entfernt werden.
Ich denke, ich könnte die Funktion fallen lassen und den Rohcode einfach zweimal schreiben.

@Jordan24 Ohne die Anführungszeichen faltet PostgreSQL alle Bezeichner in Kleinbuchstaben um.

Alles außer der 'Enum' hart codiert, um es zu umgehen. Danke für den Tipp @kibertoad!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

aj0strow picture aj0strow  ·  3Kommentare

saurabhghewari picture saurabhghewari  ·  3Kommentare

sandrocsimas picture sandrocsimas  ·  3Kommentare

mattgrande picture mattgrande  ·  3Kommentare

nklhrstv picture nklhrstv  ·  3Kommentare