从S3直接加载嵌套JSON至Snowflake遇COPY错误,求优化方案
解决Snowflake从S3加载嵌套JSON时的COPY语句编译错误
错误原因
你碰到的SQL编译错误: COPY statement only supports simple SELECT from stage statements for import,本质是Snowflake的COPY INTO对导入用的子查询有严格限制——它只支持直接从stage读取数据的简单SELECT语句,不能包含WITH子句、FLATTEN这类表函数或者多层嵌套的复杂逻辑。你原来的语句用了WITH子句和FLATTEN,所以触发了这个报错。
优化后的直接加载方案
把逻辑简化,去掉WITH子句,直接在主查询里整合FLATTEN操作,这样就能符合COPY INTO的要求,不用临时表也能直接从S3加载:
COPY INTO schema.table_A FROM ( SELECT DISTINCT CURRENT_TIMESTAMP() AS exec_t, $1 AS data, $1:id AS id, $1:code::text AS code FROM '@public.stage' (file_format => 'public.json', pattern => 'abc/xyz/.*'), TABLE(FLATTEN($1)) f );
方案说明
- 直接从S3 stage读取
$1(对应JSON文件里的每个顶层对象/数组),无需用WITH子句包装 - 把
FLATTEN($1)直接作为关联表,和stage数据源并列查询,完全符合COPY INTO对"简单SELECT"的定义 - 完整保留了你原来需要的字段提取、去重(DISTINCT)和执行时间戳(exec_t)逻辑
额外提示
如果你的JSON文件是外层带数组的格式(比如[{"id":1,...}, {"id":2,...}]),可以在public.json文件格式里设置STRIP_OUTER_ARRAY = TRUE,这样Snowflake会自动把数组拆成单独的行,可能不需要额外用FLATTEN,语句会更简洁:
COPY INTO schema.table_A FROM ( SELECT DISTINCT CURRENT_TIMESTAMP() AS exec_t, $1 AS data, $1:id AS id, $1:code::text AS code FROM '@public.stage' (file_format => 'public.json', pattern => 'abc/xyz/.*') );
内容的提问来源于stack exchange,提问作者Kar
相关产品推荐
相关产品推荐

