PostgreSQL изменить тип столбца с DATERANGE на TSTZRANGE и перенести данные - PullRequest
0 голосов
/ 26 февраля 2020

Мы меняем столбец run_dates (для каждого запроса) с daterange на tstzrange, столбец с тестовыми данными за несколько месяцев. По сути, мы хотим выполнить миграцию!

Я запускаю приведенный ниже скрипт, вдохновленный postgreSQL изменением типа данных столбца на отметку времени без часового пояса , и я должен признать, что мой SQL фон в основном ничто

-- Create a temporary TIMESTAMP column
ALTER TABLE table_name ADD COLUMN run_dates_holder TSTZRANGE NULL;

-- Copy casted value over to the temporary column
UPDATE table_name SET run_dates_holder = run_dates::TSTZRANGE;

-- Modify original column using the temporary column
ALTER TABLE table_name ALTER COLUMN run_dates TYPE
TSTZRANGE USING run_dates_holder;

-- Drop the temporary column (after examining altered column values)
ALTER TABLE table_name DROP COLUMN run_dates_holder;

К сожалению ..... Эти типы не переводятся естественным образом

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) cannot cast type daterange to tstzrange 

и

psycopg2.ProgrammingError: cannot cast type daterange to tstzrange
LINE 5: ...ble_name SET run_dates_holder = run_dates::TSTZRANG...

Кто-нибудь когда-либо успешно переносил диапазон дат в диапазон tstzrange?

В качестве резервной копии мы можем просто удалить столбец диапазона дат и создать заново. как tzzrange, так как это повлияет только на тестовые данные. Просто менее оптимально для команды. Стоит попытаться разобраться в этом, и я думаю, что решение здесь, по крайней мере, стоит будущим мигрантам «daterange-to-tzzrange», так как я не нашел других документов / ресурсов по этому вопросу

Ответы [ 2 ]

2 голосов
/ 26 февраля 2020

Вы не можете просто привести дату к tzzrange. Используйте lower() и upper() для извлечения границ daterange и upper_inc() и lower_inc() для извлечения их инклюзивности, и создайте новый tstzrange.

UPDATE table_name
SET run_dates_holder=tstzrange(
  lower(run_dates), upper(run_dates),
  concat(
    CASE WHEN lower_inc(run_dates) THEN '[' else '(' END,
    CASE WHEN upper_inc(run_dates) THEN ']' ELSE ')' END)
  );
0 голосов
/ 28 февраля 2020

Используя строку из ответа AdamKG (выбранную как ЛУЧШИЙ!), Мы приходим к этому

-- -- Create a placeholder tstzrange column
ALTER TABLE SB ADD COLUMN run_dates_holder tstzrange NULL;

-- -- Update placeholder tstzrange column with existing run_dates
UPDATE SB SET run_dates_holder=tstzrange(lower(run_dates), upper(run_dates),'[)');

-- -- Remove original run_dates
ALTER TABLE SB DROP COLUMN run_dates;

-- -- Rename 'run_dates_holder' to 'run_dates'
ALTER TABLE SB RENAME COLUMN run_dates_holder to run_dates;

Тестовые данные остались нетронутыми

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...