Я хочу написать строку миграции, чтобы добавить новую строку к типу столбца 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
а затем создать новый, если измененный тип столбца - enum.
Я бы хотел, чтобы эта функция была реализована.
@elhigu Я написал собственный запрос перечисления, чтобы я мог использовать перечисления Postgres, однако в сообществе Postgres ведутся споры об условиях проверки и перечислениях
Просто для всех, кто хочет знать, как _может_ выглядеть код в 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 Спасибо за пример кода миграции. Именно то, что я искал. Однако я столкнулся с одной проблемой. «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'
])
);
};
Если я заключу имя столбца в двойные кавычки, я получаю синтаксическую ошибку, потому что одинарные кавычки не удаляются в исходном коде.
Я думаю, что могу отказаться от этой функции и просто дважды написать необработанный код.
@ Jordan24 Без кавычек PostgreSQL
Жестко закодированы все, кроме enum, чтобы обойти это. Спасибо за подсказку @kibertoad!
Самый полезный комментарий
Просто для всех, кто хочет знать, как _может_ выглядеть код в Postgres 9