如何将含双引号与逗号字段的csv.gz文件从S3加载至Snowflake?
解决方案
1. 改用自定义分隔符(优先推荐)
如果能重新生成源文件,直接把分隔符换成不会出现在字段内容里的特殊字符,比如竖线|、脱字符^或者制表符\t,之后在COPY命令里指定即可:
COPY INTO your_target_table FROM @your_s3_stage FILE_FORMAT = (TYPE = CSV FIELD_DELIMITER = '|' SKIP_HEADER = 1 COMPRESSION = GZIP);
要是没法重新生成文件,也可以用S3的Lambda函数批量处理:先把字段内的逗号临时转义,再用新分隔符替换原逗号,处理完再加载到Snowflake。
2. 用Snowflake COPY高级参数适配
试试结合ESCAPE参数转义字段内的特殊字符:
COPY INTO your_target_table FROM @your_s3_stage FILE_FORMAT = (TYPE = CSV FIELD_OPTIONALLY_ENCLOSED_BY = '"' ESCAPE = '\\' SKIP_HEADER = 1 COMPRESSION = GZIP);
如果源文件里的双引号是用双引号自身转义的(比如""代表一个双引号),可以设置ESCAPE_UNENCLOSED_FIELD = NONE,保留FIELD_OPTIONALLY_ENCLOSED_BY = '"':
COPY INTO your_target_table FROM @your_s3_stage FILE_FORMAT = (TYPE = CSV FIELD_OPTIONALLY_ENCLOSED_BY = '"' ESCAPE_UNENCLOSED_FIELD = NONE SKIP_HEADER = 1 COMPRESSION = GZIP);
3. 先按半结构化数据加载再解析
先把整个CSV行作为单个字段加载到临时表,再用字符串函数拆分处理:
- 创建临时表:
CREATE TEMP TABLE temp_raw_data (raw_line STRING);
- 加载整行数据:
COPY INTO temp_raw_data FROM @your_s3_stage FILE_FORMAT = (TYPE = CSV FIELD_DELIMITER = '~' -- 选一个绝对不会出现在内容里的字符,让整行成为单个字段 SKIP_HEADER = 1 COMPRESSION = GZIP);
- 用正则提取各个字段:
INSERT INTO your_target_table (col1, col2, col3) SELECT REGEXP_SUBSTR(raw_line, '^"([^"]|"")*"|([^,]+)', 1, 1, 'e') AS col1, REGEXP_SUBSTR(raw_line, '^"([^"]|"")*",?"([^"]|"")*"|([^,]+)', 1, 2, 'e') AS col2, REGEXP_SUBSTR(raw_line, '^"([^"]|"")*",?"([^"]|"")*",?"([^"]|"")*"|([^,]+)', 1, 3, 'e') AS col3 FROM temp_raw_data;
这个正则能匹配被双引号包裹且内部含转义双引号的字段,也能匹配未被包裹的普通字段。
4. S3端预处理文件
用S3批量操作结合Python脚本,批量处理.gz文件:
- 先解压文件,遍历每行,识别被双引号包裹的字段,把字段内的逗号换成临时标记(比如
{{COMMA}}) - 处理完重新压缩成.gz,再用Snowflake加载,最后把临时标记替换回逗号:
UPDATE your_target_table SET target_col = REPLACE(target_col, '{{COMMA}}', ',');
内容的提问来源于stack exchange,提问作者Rajalakshmi
相关产品推荐
相关产品推荐

