使用 for 循环从 s3 复制 Redshift

Posted

技术标签:

【中文标题】使用 for 循环从 s3 复制 Redshift【英文标题】:Redshift Copy from s3 using for loop 【发布时间】:2021-04-03 04:10:58 【问题描述】:

我有很多文件要加载到 S3 中。 我已经在文件的每个前缀处创建了清单文件。

例如,在 s3://my-bucket/unit_1 我有如下文件。

chunk1.csv.gz
chunk2.csv.gz
chunk3.csv.gz
cunkk4.csv.gz 
unit.manifest

所以使用复制命令,我可以将unit_1 文件加载到redshift

但是,我有超过 1000 个单位,所以我想用循环来做。 所以我想做一个从 1 到 1000 的循环来改变清单文件的前缀。

所以我确实喜欢下面,

create or replace procedure copy_loop()
language plpgsql
as $$
BEGIN
    FOR i in 1..1000 LOOP
    COPY mytable
    FROM 's3://my-bucket/unit_%/unit.manifest', i 
    credentials 'aws_iam_role=arn:aws:iam::myrolearn'
    MANIFEST
    REGION 'ap-northeast-2'
    REMOVEQUOTES
    IGNOREHEADER 1
    ESCAPE
    DATEFORMAT 'auto'
    TIMEFORMAT 'auto'
    GZIP
    DELIMITER '|'
    ACCEPTINVCHARS '?'
    COMPUPDATE FALSE
    STATUPDATE FALSE
    MAXERROR 0
    BLANKSASNULL
    EMPTYASNULL
    NULL AS '\N'
    EXPLICIT_IDS;
    END LOOP;
END; 
$$;

但我收到了这条消息

SQL 错误 [500310] [42601]:Amazon 无效操作:“,”或附近的语法错误;

我该如何处理?

【问题讨论】:

如果解决方案对您有帮助,请点赞,以便将来帮助其他人:) 【参考方案1】:

这是我的解决方案。

create or replace procedure copy_loop(i1 int, i2 int)
language plpgsql
as $$
DECLARE 
    prefix TEXT := 's3://mybucket/unit_';
    manifest TEXT := '/unit.manifest' ;
    manifest_location TEXT ;
    copy_commands VARCHAR(2000) ;
    copy_options VARCHAR(2000) := 'credentials '|| quote_literal('aws_iam_role=myrolearn')
    || ' MANIFEST '
    || ' REGION ' || quote_literal('ap-northeast-2')
    || ' REMOVEQUOTES '
    || ' IGNOREHEADER 1 '
    || ' ESCAPE '
    || ' DATEFORMAT ' || quote_literal('auto')
    || ' TIMEFORMAT ' || quote_literal('auto')
    || ' GZIP '
    || ' DELIMITER ' ||  quote_literal('|')
    || ' ACCEPTINVCHARS ' || quote_literal('?')
    || ' COMPUPDATE FALSE '
    || ' STATUPDATE FALSE '
    || ' MAXERROR 0 '
    || ' BLANKSASNULL '
    || ' EMPTYASNULL '
    || ' NULL AS ' || quote_literal('\N')
    || ' EXPLICIT_IDS ';
BEGIN 
    FOR i in i1..i2 LOOP
        manifest_location := prefix || i || manifest;
        copy_commands := 'COPY mytable FROM' || quote_literal(manifest_location) || copy_options;
        execute copy_commands;
    END LOOP;
END;
$$;

使用这个程序,我可以从 1000 多个单元复制文件。 还设置循环的起始编号和结束编号有助于划分加载作业。由于大量加载需要几个小时,我认为最好使用一些块来完成加载工作。

【讨论】:

以上是关于使用 for 循环从 s3 复制 Redshift的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从 s3 到 redshift db 的复制命令解决语法错误

AWS:使用从 s3 到 redshift 的复制命令时没有插入任何内容

将 csv 文件从 s3 复制到 redshift 的问题

尝试加载 Redshift 样本,从 S3 复制时拒绝访问

从 S3 接入点复制到 Redshift

使用复制命令将数据从 s3 加载到 redshift