barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

среда, 30 мая 2012 г.

Изменение enum-типа в PostgreSQL 8.3

Задача:

Изменить пользовательский перечислимый тип, используемый в одной из колонок БД (переименовать одно из значений типа).

Решение:

Сделать это оказалось не очень-то просто. В интернете нашел следующее решение (правда, для случая добавления нового значения в 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-команды):
  1. Создаем временную колонку с типом "text", и переносим в неё данные из колонки enum-типа, используя ::text:
  2. UPDATE mytable SET mycol_tmp = mycol::text
  3. Удаляем старую колонку и старый enum-тип
  4. Создаем новый тип, называя его также, как только что удаленный
  5. Создаем колонку взамен удаленной, задав её типом только что созданный тип
  6. Переносим в эту колонку данные из временной колонки,  преобразуя их при необходимости (например, переименовывая старые значения enum`а в новые) и приводя их к перечислимому типу с помощью ::myenum.
  7. Удаляем временную колонку

Комментариев нет:

Отправить комментарий