如何在Redshift COPY命令中动态读取带日期的S3文件夹
如何在Redshift COPY命令中动态读取带日期的S3文件夹
嗨,我来帮你搞定这个问题!你之前遇到的语法错误,本质是Redshift的COPY命令不支持直接在FROM子句里用字符串拼接表达式——COPY的路径参数必须是一个静态字符串,或者通过动态SQL生成完整的COPY语句后再执行才行。下面给你两种实用的解决方案:
方案一:使用匿名块执行动态SQL
你可以把整个COPY命令拼成字符串,然后用EXECUTE命令执行。注意要转义字符串里的单引号(用两个单引号表示一个),示例代码如下:
BEGIN EXECUTE 'COPY temp_table FROM ''s3://cluster-name/folder1/folder2/year=' || date_part(year, current_date)::varchar || '/month=' || lpad(date_part(month, current_date)::varchar,2,'0') || '/day=' || lpad(date_part(day, current_date)::varchar,2,'0') || '/'' iam_role ''xxxxxxx'' region ''xxxxx'' format as json ''auto'';'; END;
方案二:封装成存储过程(更适合调度)
如果这个COPY操作是要定期调度的,把逻辑封装成存储过程会更方便维护,还能避免单引号转义的麻烦(用format函数自动处理):
CREATE OR REPLACE PROCEDURE copy_daily_s3_data() LANGUAGE plpgsql AS $$ DECLARE s3_path VARCHAR; BEGIN -- 生成当天的S3分区路径 s3_path := 's3://cluster-name/folder1/folder2/year=' || date_part(year, current_date)::varchar || '/month=' || lpad(date_part(month, current_date)::varchar,2,'0') || '/day=' || lpad(date_part(day, current_date)::varchar,2,'0') || '/'; -- 用format函数构造并执行COPY命令,自动处理单引号转义 EXECUTE format('COPY temp_table FROM %L iam_role %L region %L format as json ''auto'';', s3_path, 'xxxxxxx', 'xxxxx'); END; $$; -- 调用存储过程执行数据导入 CALL copy_daily_s3_data();
额外小提示
如果你的调度需求是每天导入前一天的数据(这是更常见的场景),只需要把current_date改成current_date - interval '1 day'即可,比如:
s3_path := 's3://cluster-name/folder1/folder2/year=' || date_part(year, current_date - interval '1 day')::varchar || '/month=' || lpad(date_part(month, current_date - interval '1 day')::varchar,2,'0') || '/day=' || lpad(date_part(day, current_date - interval '1 day')::varchar,2,'0') || '/';
备注:内容来源于stack exchange,提问作者Jams1997
相关产品推荐
相关产品推荐

