2012-05-25 3 views
1

Существует такая ситуация: мне нужно изменить в целом БД для всех таблиц полого типа данных «временной метка без часового пояса» до «метки времени (0) с временной зоной»Postgres изменения типа массива данных

Я решил создать функцию:

CREATE OR REPLACE FUNCTION grd_replace_datetime_with_timezone() 
    RETURNS character varying AS 
$BODY$ 

DECLARE 
    old_column RECORD; 
    s text; 
BEGIN 

FOR old_column IN (
    SELECT 
     isc.table_schema as table_schema, 
     isc.table_name as table_name, 
     isc.column_name as column_name 
    FROM 
     information_schema.columns isc 
    INNER JOIN 
     pg_tables pt 
      ON (isc.table_schema = pt.schemaname and isc.table_name = pt.tablename) 
    WHERE 
     isc.column_name like '%date%' and 
     isc.table_schema in ('public') and 
     isc.data_type = 'timestamp without time zone' 
    ORDER BY 
     isc.table_name ASC 
    ) 
LOOP 
    RAISE NOTICE 'Schema: %',old_column.table_schema; 
    RAISE NOTICE 'Table: %',old_column.table_name; 
    RAISE NOTICE 'Column %',old_column.column_name; 


    EXECUTE 'ALTER TABLE '||old_column.table_schema||'.'||old_column.table_name||' 
       ALTER COLUMN '||old_column.column_name||' TYPE timestamp(0) with time zone'; 

    RAISE NOTICE '-------------------------------------------------------------------------------'; 
    RAISE NOTICE ''; 
END LOOP; 


RETURN 'S'; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

Но есть проблема: некоторые виды зависят от этих столбцов которым нужно изменить. и получил ошибку:

ERROR: cannot alter type of a column used by a view or rule 

также я получил ошибку об индексах.

Любые идеи о том, как изменить тип данных для всех db-систем, где тип данных без часового пояса?

ответ

1

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

Я вижу два possibilitiese:

  • DROP все зависящие мнения до изменения типа и воссоздать их потом

  • Совершенно иной подход: самосвала база данных, изменить таблица определения в дампе и восстановление это. Пока вы делаете то, что в том же часовом поясе, timestamp without time zone следует поправить с точностью до timestamp(0) with time zone.

Если у вас есть более чем несколько объектов, свалка & восстановления является путь. Я согласен с @wildplasser в комментарии там.
Вы можете быть заинтересованы в этой всеобъемлющей related answer on PostgreSQL timestamp handling:


Быстрый тест, чтобы проверить мое утверждение:

CREATE TEMP TABLE t (id int, x timestamp without time zone); 
CREATE TEMP TABLE t1 (id int, x timestamp(0) with time zone); 
INSERT INTO t VALUES 
(1, '2012-05-25 13:23:03.0123') 
,(2, '2012-05-25 23:23:03') 
,(3, '2012-05-25 0:0:0'); 

COPY t TO '/var/lib/postgres/ts_test.sql'; 
COPY t1 FROM '/var/lib/postgres/ts_test.sql'; 

SELECT t.x, t.x::timestamp(0) with time zone, t1.x 
FROM t 
JOIN t1 USING (id); 

Принуждение осуществляется автоматически и правильно.

+1

IMHO dump + edit + restore - единственная нормальная вещь. Помимо представлений/правил, есть также ссылки, которые «невидимы» для схемы, такие как функции и триггеры. И: с отдельными -схемами и только -data-дамами, редактирование - это не более чем sed-задание. – wildplasser

+0

@wildplasser: Я согласен, это больше, чем рука, полная объектов, это путь. –

+0

Массовое редактирование - тайный талант DBA!/ g – wildplasser

1

Вы можете попробовать его с pg_dump

первым сделать дамп с --format = обычная --schema-только

Измените тип данных в файле дампа и восстановить его в новом дб.

Чем вы создаете дамп с --data-only и восстанавливаете их в новом db.

Смежные вопросы