postgres批量数据类型更改

时间:2012-05-25 10:29:08

标签: sql postgresql types timestamp database-migration

我需要将整个数据库中的所有表格列从数据类型timestamp without time zone更改为timestamp(0) {{ 1}} with
所以我创建了这个函数:

time zone

但是有些视图依赖于受影响的列而我收到了错误:

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;

我也有关于索引的错误。

如何更改所有ERROR: cannot alter type of a column used by a view or rule 列的数据类型?

2 个答案:

答案 0 :(得分:1)

据我所知,当数据类型发生变化时,没有内置的方法来自动更改视图 我看到两种可能性:

  1. DROP 在类型更改之前所有依赖视图,之后重新创建

  2. 一种完全不同的方法:转储数据库,更改转储中的表定义并恢复。只要您在同一时区内执行 timestamp without time zone就应该被正确强制转移到timestamptz(0)。请注意,转化为timestamptz(0) 轮次为完整秒数。

  3. 如果您有多个对象,则转储&恢复是可行的方法 - 如果你能负担得起的停机时间。

    演示

    CREATE TEMP TABLE t  (id int, x timestamp);
    CREATE TEMP TABLE t1 (id int, x timestamptz(0);
    
    INSERT INTO t VALUES
     (1, '2019-05-25 13:23:03.123')  -- rounds down
     (1, '2019-05-25 13:23:03.987')  -- rounds up
    ,(2, '2019-05-25 23:23:03')
    ,(3, '2019-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::timestamptz(0), t1.x
    FROM   t
    JOIN   t1 USING (id);
    

    强制自动且正确地发生。

    相关:

答案 1 :(得分:1)

您可以尝试使用pg_dump

首先使用--format = plain --schema-only

进行转储

更改转储文件中的数据类型,并将其还原到新的数据库中。

比使用--data-only进行转储并在新数据库中恢复它们。