在 Postgres 上删除枚举值是否有限制
Are there restrictions on removing an enum value on Postgres
我试图从 Postgres 的枚举中删除一个值,但一直失败。我之前已经做过很多次了,没有任何问题,所以我不确定是否发生了变化,或者我是否 运行 进入了一些边缘案例限制。
这是我的 运行(删除枚举 FOURTH
):
ALTER TYPE "my_enum" RENAME TO "my_enum_old";
CREATE TYPE "my_enum" AS ENUM('FIRST', 'SECOND', 'THIRD', 'FIFTH');
ALTER TABLE "my_Table" ALTER COLUMN "my_column" TYPE "my_eum" USING "my_column"::"text"::"my_enum";
DROP TYPE "my_enum_old";
也许枚举名称的长度有大小限制?我们的枚举全名如下长度(Xs用来隐藏真实姓名)XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX
并在末尾添加 old
时添加另一个 _OLD
.
返回的错误是
ERROR: operator does not exist: my_enum = my_enum_old
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
默认 Postgres identifiers have a limit of 63 bytes。你应该得到这样的警告:
NOTICE: identifier "XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX_OLD" will be truncated to "XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX_OL"
ALTER TYPE
您必须选择一个较短的标识符。
注意:虽然 XXX
和 xxx
是相同的标识符,但 "XXX"
和 XXX
是 不同的 标识符。如果有时你使用双引号有时你没有,那可能会导致问题。
这就是为什么除非必要,否则应该避免引用标识符。
请注意,在这种情况下,您可以简单地重命名该值,而不是重新创建枚举。
alter type my_enum rename value 'FOURTH' to 'FIFTH';
如果您发现自己经常更改枚举,并且有这么多枚举需要大标识符,这可能不是枚举的好用法。考虑加入 table。
create table thing_names (
id bigserial primary key,
label not null text
);
insert into things values
(1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD'), (4, 'FOURTH');
create table stuff (
id bigserial primary key,
thing_id bigint not null references things
);
insert into stuff values (1, 1), (2, 4), (3, 2);
select stuff.id, things.label
from stuff
join things on stuff.thing_id = things.id;
id | label
----+--------
1 | FIRST
2 | FOURTH
3 | SECOND
update things set label = 'FIFTH' where id = 4;
select stuff.id, things.label
from stuff
join things on stuff.thing_id = things.id;
id | label
----+--------
1 | FIRST
2 | FIFTH
3 | SECOND
最有可能的问题是您在 table 上有一个检查约束,它执行如下操作:
check (not(my_column = 'FOURTH'::my_enum_old)));
一旦 my_column 更改了类型,就无法再检查该约束。只需删除约束。
我试图从 Postgres 的枚举中删除一个值,但一直失败。我之前已经做过很多次了,没有任何问题,所以我不确定是否发生了变化,或者我是否 运行 进入了一些边缘案例限制。
这是我的 运行(删除枚举 FOURTH
):
ALTER TYPE "my_enum" RENAME TO "my_enum_old";
CREATE TYPE "my_enum" AS ENUM('FIRST', 'SECOND', 'THIRD', 'FIFTH');
ALTER TABLE "my_Table" ALTER COLUMN "my_column" TYPE "my_eum" USING "my_column"::"text"::"my_enum";
DROP TYPE "my_enum_old";
也许枚举名称的长度有大小限制?我们的枚举全名如下长度(Xs用来隐藏真实姓名)XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX
并在末尾添加 old
时添加另一个 _OLD
.
返回的错误是
ERROR: operator does not exist: my_enum = my_enum_old
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
默认 Postgres identifiers have a limit of 63 bytes。你应该得到这样的警告:
NOTICE: identifier "XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX_OLD" will be truncated to "XXXXXXXXXXXXX_XXXXXXX_XXXXXXXX_XXXXXXXXX_XXXXXXXX_XXXXX_XXXX_OL"
ALTER TYPE
您必须选择一个较短的标识符。
注意:虽然 XXX
和 xxx
是相同的标识符,但 "XXX"
和 XXX
是 不同的 标识符。如果有时你使用双引号有时你没有,那可能会导致问题。
这就是为什么除非必要,否则应该避免引用标识符。
请注意,在这种情况下,您可以简单地重命名该值,而不是重新创建枚举。
alter type my_enum rename value 'FOURTH' to 'FIFTH';
如果您发现自己经常更改枚举,并且有这么多枚举需要大标识符,这可能不是枚举的好用法。考虑加入 table。
create table thing_names (
id bigserial primary key,
label not null text
);
insert into things values
(1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD'), (4, 'FOURTH');
create table stuff (
id bigserial primary key,
thing_id bigint not null references things
);
insert into stuff values (1, 1), (2, 4), (3, 2);
select stuff.id, things.label
from stuff
join things on stuff.thing_id = things.id;
id | label
----+--------
1 | FIRST
2 | FOURTH
3 | SECOND
update things set label = 'FIFTH' where id = 4;
select stuff.id, things.label
from stuff
join things on stuff.thing_id = things.id;
id | label
----+--------
1 | FIRST
2 | FIFTH
3 | SECOND
最有可能的问题是您在 table 上有一个检查约束,它执行如下操作:
check (not(my_column = 'FOURTH'::my_enum_old)));
一旦 my_column 更改了类型,就无法再检查该约束。只需删除约束。