在 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

您必须选择一个较短的标识符。


注意:虽然 XXXxxx 是相同的标识符,但 "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 更改了类型,就无法再检查该约束。只需删除约束。