Knex: 質問:knex移行で列挙型の列タイプを更新します

作成日 2016年09月27日  ·  10コメント  ·  ソース: knex/knex

スタックオーバーフロー

列挙型の列タイプに新しい文字列を追加するための移行文字列を作成しようとしています。 service列にgammaを追加しようとしています。

以下のコードで試してみました。 テーブルと列がすでに存在するため、これは衝突します。

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

最も参考になるコメント

Postgres9でコードがどのように見えるかを知りたい人のためだけに

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

全てのコメント10件

これにぶつかって、 alter APIを使用する方法

現在、列挙型はチェック制約を使用して実行されており、 .alter()は特別な処理はありません...

1つの問題は、 .alter()が列の元のタイプを認識していないため、列挙型の古いチェック制約を削除する必要があるかどうかがわからないことです。

私の知る限り、現在、許可されている列挙値は、古いものを削除して新しいチェック制約を作成することにより、 knex.rawのみ変更できます...

変更された列のタイプが列挙型の場合は、 drop old constraint if existで実装してから、新しいものを作成できると思います。

この機能が実装されるのを楽しみにしています。

@elhigu Postgres列挙型を使用できるようにカスタム列挙型クエリを作成しましたが、Postgresコミュニティではチェック条件と列挙型についていくつかの議論があります

Postgres9でコードがどのように見えるかを知りたい人のためだけに

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移行コードの例をありがとう。 まさに私が探していたもの。 しかし、私は1つの問題に直面しています。 'myColumnName'は、移行時にエラーをスローします。 メッセージには、「列 'mycolumnname'は存在しません」と表示されます。 キャメルケースがなくなっていることに注意してください。 それを回避する方法についてのアイデアはありますか?

@ Jordan24コードを共有できますか?

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

columnNameを二重引用符で囲むと、生のコードで一重引用符が削除されないため、構文エラーが発生します。
関数を削除して、生のコードを2回書き出すだけかもしれないと思います。

@ Jordan24引用符なしで、PostgreSQLはすべての識別子を小文字に折り畳みます。

それを回避するために、「列挙型」以外のすべてをハードコーディングしました。 ヒント@kibertoadをありがとう!

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

mtom55 picture mtom55  ·  3コメント

aj0strow picture aj0strow  ·  3コメント

hyperh picture hyperh  ·  3コメント

fsebbah picture fsebbah  ·  3コメント

koskimas picture koskimas  ·  3コメント