我正在寻找编写迁移字符串以将新字符串添加到 enum 列类型。 我正在尝试将gamma
到service
列中。
我在下面尝试使用此代码。 这会发生冲突,因为表和列已经存在。
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()
对它们没有任何特殊处理......
一个问题是.alter()
不知道列的原始类型是什么,这就是为什么它不知道是否应该删除枚举的旧检查约束。
据我所知,目前只能通过删除旧的并创建新的检查约束来使用knex.raw
更改允许的枚举值...
我认为它可以通过一些drop old constraint if exist
,然后如果列的更改类型是枚举,则创建一个新的。
我很想看到这个功能被实现。
@elhigu我写了一个自定义枚举查询,以便我可以使用 Postgres 枚举,但是 Postgres 社区中存在一些关于检查条件与枚举的争论
仅适用于任何想知道 Postgres 9 中的代码 _might_ 外观的人
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感谢您提供迁移代码示例。 正是我正在寻找的。 不过我遇到了一个问题。 'myColumnName' 在迁移时抛出错误。 该消息说“列'mycolumnname' 不存在”。 请注意,camelCase 现在丢失了。 关于如何解决这个问题的任何想法?
@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 用双引号括起来,则会出现语法错误,因为原始代码中未删除单引号。
我想我可能会放弃这个函数,只写两次原始代码。
@Jordan24如果没有引号,PostgreSQL
硬编码除“枚举”之外的所有内容以解决它。 感谢@kibertoad 的提示!
最有用的评论
仅适用于任何想知道 Postgres 9 中的代码 _might_ 外观的人