在 postgres 中删除单个枚举值

the*_*uls 4 postgresql enums postgresql-9.5

假设我有以下枚举:

CREATE TYPE "my_enum" AS ENUM('value1', 'value2', 'value3');
Run Code Online (Sandbox Code Playgroud)

我想要删除value3。从我在文档和以前的线程中看到的内容来看,我实际上必须删除整个枚举并使用我想要的值重新创建它。像这样的东西:

DROP TYPE IF EXISTS "my_enum";

CREATE TYPE "my_enum" AS ENUM('value1', 'value2');
Run Code Online (Sandbox Code Playgroud)

问题是我有其他依赖于这个枚举的表,所以它不允许我这样做。我收到以下消息(理所当然):

错误:无法删除类型“my_enum”,因为其他对象依赖于它

所以我的问题是如何在不删除整个内容的情况下删除一个枚举值?我知道我可以通过更改以下内容轻松添加值:

ALTER TYPE "my_enum" ADD VALUE 'value4';
Run Code Online (Sandbox Code Playgroud)

所以我认为我可以在删除时做一些等效的事情。

谢谢!

kli*_*lin 7

您必须删除该类型,但是,您可以临时更改包含该类型列的表。

示例模型:

create type my_enum as enum('apple', 'pear', 'banana');
create table my_table(id serial primary key, my_col my_enum);
insert into my_table (my_col) values
    ('apple'),
    ('pear');
Run Code Online (Sandbox Code Playgroud)

banana从枚举类型中删除:

alter table my_table alter my_col type text;
drop type my_enum;
create type my_enum as enum('apple', 'pear');
alter table my_table alter my_col type my_enum using my_col::my_enum;
Run Code Online (Sandbox Code Playgroud)

查看:

select * from my_table;

 id | my_col 
----+--------
  1 | apple
  2 | pear
(2 rows)    
Run Code Online (Sandbox Code Playgroud)


S-M*_*Man 6

嗯,虽然确实不推荐,但如果您有权这样做,有一种方法可以实现这一目标:

SELECT 
    t.typname,
    e.enumlabel,
    e.enumtypid
FROM pg_type t
JOIN pg_enum e ON e.enumtypid = t.oid
WHERE t.typname = '<your enum name>'
Run Code Online (Sandbox Code Playgroud)

enumtypid这为您提供了枚举类型的dbms 内部 id 。

这样你就可以进行删除:

DELETE FROM pg_enum
WHERE enumtypid = <your enumtypid>
    AND enumlabel = '<enum value to delete>'
Run Code Online (Sandbox Code Playgroud)

您必须确保在此之前不再使用该值。否则你的表可能会损坏!