Redshift 使用 for 循环从 s3 复制

Redshift Copy from s3 using for loop

我有很多文件要加载到 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 Error [500310] [42601]: Amazon Invalid operation: syntax error at or near ",";

我该如何处理?

这是我的解决方案。

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 多个单元中复制文件。 还设置循环的起始编号和结束编号有助于划分加载作业。由于大量加载需要几个小时,我认为加载一些块会更好。