Задача:
Изменить пользовательский перечислимый тип, используемый в одной из колонок БД (переименовать одно из значений типа).
Решение:
Сделать это оказалось не очень-то просто. В интернете нашел следующее решение (правда, для случая добавления нового значения в enum-тип, но не в этом суть):
-- 1. Переименуйте тот тип ENUM который вы хотите дополнить
ALTER TYPE b_status RENAME TO old_b_status;
-- 2. Создайте новый тип
CREATE TYPE b_status AS ENUM ('exposed','paid','canceled');
-- 3. Переименуйте столбец, который использует ваш старый тип
ALTER TABLE bills RENAME COLUMN status TO old_status;
-- 4. Создайте новый столбец с новым типом
ALTER TABLE bills ADD status b_status NOT NULL DEFAULT 'exposed';
-- 5. Скопируйте значения в новый столбец
UPDATE bills SET status = old_status::text::b_status;
-- 6. Удалите старый столбец и тип
ALTER TABLE bills DROP COLUMN old_status;
DROP TYPE old_b_status;
Проблема только в том, что на моем серваке - PostgreSQL 8.3, и команды ALTER TYPE ... RENAME в нём нет (http://www.postgresql.org/docs/8.3/static/sql-altertype.html), т.к. эта фича появилась только в 8.4. Так что последовательность получилась другая (часть действий делал в GUI pgAdmin, поэтому приведу лишь порядок действий, а не сами SQL-команды):
- Создаем временную колонку с типом "text", и переносим в неё данные из колонки enum-типа, используя ::text:
- Удаляем старую колонку и старый enum-тип
- Создаем новый тип, называя его также, как только что удаленный
- Создаем колонку взамен удаленной, задав её типом только что созданный тип
- Переносим в эту колонку данные из временной колонки, преобразуя их при необходимости (например, переименовывая старые значения enum`а в новые) и приводя их к перечислимому типу с помощью ::myenum.
- Удаляем временную колонку
UPDATE mytable SET mycol_tmp = mycol::text
Комментариев нет:
Отправить комментарий