Подтвердить что ты не робот

Переименовать элемент перечисления в PostgreSQL

Я хотел бы изменить имя элемента в перечисляемом типе в PostgreSQL 9.1.5.

Вот тип create stmt:

CREATE TYPE import_action AS ENUM
('Ignored',
'Inserted',
'Updated',
'Task created');

Я просто хочу изменить "Задача создана" на "Прервано". Похоже, что из документации, что должно работать следующее:

ALTER TYPE import_action
RENAME ATTRIBUTE "Task created" TO "Aborted"; 

Однако я получаю сообщение msg:

********** Error **********

ERROR: relation "import_action" does not exist
SQL state: 42P01

Но это явно существует.

Тип в настоящее время используется более чем одной таблицей.

Я думаю, что не должно быть способа сделать это. Я пробовал диалог для типа в pgAdminIII, но я не вижу возможности переименовать его там. (Итак, либо сильный намек, что я не могу этого сделать, либо - я надеюсь - небольшой надзор за разработчиком, который создал этот диалог)

Если я не могу сделать это в одном статусе? Тогда что мне нужно сделать? Должен ли я написать script, чтобы добавить элемент, обновить все записи до нового значения, а затем удалить старый элемент? Будет ли это работать?

Кажется, это должно быть просто. Насколько я понимаю, записи просто сохраняют ссылку на тип и элемент. Я не думаю, что они на самом деле хранят текстовое значение, которое я ему дал. Но, возможно, я тоже здесь не прав.

4b9b3361

Ответ 1

Имена значений перечисления называются ярлыками, атрибуты - это совсем другое.

К сожалению, изменение названий переименований непросто, вам нужно гасить системный каталог: http://www.postgresql.org/docs/9.1/static/catalog-pg-enum.html

UPDATE pg_enum SET enumlabel = 'Aborted' 
WHERE enumlabel = 'Task created' AND enumtypid = (
  SELECT oid FROM pg_type WHERE typname = 'import_action'
)

Ответ 2

Запрос в принятом ответе не учитывает имена схем. Здесь более безопасный (и более простой), основанный на http://tech.valgog.com/2010/08/alter-enum-in-postgresql.html

UPDATE pg_catalog.pg_enum
SET enumlabel = 'NEW_LABEL'
WHERE enumtypid = 'SCHEMA_NAME.ENUM_NAME'::regtype::oid AND enumlabel = 'OLD_LABEL'
RETURNING enumlabel;

Обратите внимание, что для этого требуется прямое разрешение "rolcatupdate" ( "Обновить каталог" ) - даже быть суперпользователем недостаточно.

Кажется, что обновление каталога напрямую остается единственным способом с PostgreSQL 9.3.

Ответ 3

Существует разница между типами, атрибутами и значениями. Вы можете создать перечисление, подобное этому.

CREATE TYPE import_action AS ENUM
('Ignored',
'Inserted',
'Updated',
'Task created');

Сделав это, вы можете добавить значения в перечисление.

ALTER TYPE import_action 
ADD VALUE 'Aborted';

Но синтаксическая диаграмма не отображает поддержки для удаления или переименования значения. Синтаксис, на который вы смотрели, был синтаксисом для переименования атрибута, а не значения.

Хотя этот дизайн, возможно, удивителен, он также преднамерен. Из списка рассылки pgsql-hackers.

Если вам нужно изменить используемые значения или хотите узнать, что такое целое число, вместо этого используйте таблицу поиска. Перечисления - неправильная абстракция для вы.

Ответ 4

В PostgreSQL версии 10 добавлена ​​возможность переименовать метки enum как часть ALTER TYPE:

ALTER TYPE name RENAME VALUE existing_enum_value TO new_enum_value