从一个表动态插入另一个表并使用目标表数据类型

时间:2017-06-21 23:20:51

标签: postgresql function csv dynamic import

以下是一个函数,它是用于定期将许多CSV(可以更改)上传到Postgres 9.6 db的过程的一部分。任何人对如何改进此功能或您想要分享的其他数据上传流程有任何建议?

该功能有效(我认为),所以我想我会分享,以防其他人有用。作为一个新手,这让我永远地翻转,所以希望我可以节省一些时间。

我从各种来源+++中提取代码来创建此函数,该函数插入源表中具有匹配目标表列的所有列,在插入期间将源列中的数据类型转换为目标列的数据类型。我计划将其转换为在更新源表时执行的触发器函数。

更大的图片:1)批处理文件运行dbf2csv以将DBF导出为CSV,2)批处理文件运行csvkit以将许多CSV加载到名为dataloader的模式中的单独表中,并为CSV日期添加新列,3)下面的函数将数据从dataloader表移动到位于公共模式中的主表。我曾考虑使用PGloader,但我不懂Python。我将遇到的一个问题是,如果将新列添加到源CSV(此函数将忽略它们),但我可以手动监视,因为列的变化不大。

+++我记得一些(谢谢!)

Dynamic insert

Dynamic insert #2

Data type

More dynamic code

我尝试使用FDW并且不记得为什么我没有使用这种方法。

Foreign data wrapper

CREATE OR REPLACE FUNCTION dataloader.insert_des3 (
  tbl_des pg_catalog.regclass,
  tbl_src pg_catalog.regclass
)
RETURNS void AS
$body$
DECLARE
    tdes_cols text;
    tsrc_cols text;

BEGIN
    SET search_path TO dataloader, public;
    SELECT  string_agg( c1.attname, ',' ), 
            string_agg( quote_ident( COALESCE( c2.attname, 'NULL' ) ) || '::' || format_type(c1.atttypid, c1.atttypmod), ',' ) 
    INTO    tdes_cols,
            tsrc_cols
    FROM    pg_attribute c1 
    LEFT JOIN    pg_attribute c2 
    ON      c2.attrelid = tbl_src  
    AND     c2.attnum > 0 --attnum is the column number of c2
    AND     NOT c2.attisdropped 
    AND     c1.attname = lower(c2.attname) 
    WHERE   c1.attrelid = tbl_des
    AND     c1.attnum > 0
    AND     NOT c1.attisdropped
    AND     c1.attname <> 'id';

    EXECUTE format(
        '   INSERT INTO %I (%s)
            SELECT %s
            FROM %I
        ',
        tbl_des,  
        tdes_cols, 
        tsrc_cols, 
        tbl_src 
    );

END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

调用功能
        SELECT dataloader.insert_des('public.tbl_des','dataloader.tbl_src')

0 个答案:

没有答案