列挙型の列タイプに新しい文字列を追加するための移行文字列を作成しようとしています。 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()
})
}
これにぶつかって、 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をありがとう!
最も参考になるコメント
Postgres9でコードがどのように見えるかを知りたい人のためだけに