如何将含SUPER类型列的CSV表导入Amazon Redshift?
解决Redshift从CSV导入SUPER类型列的问题
问题根源
你的CSV数据中settings列带有Python字节串标记b'和末尾的',这不属于标准JSON格式,Redshift无法直接解析为SUPER类型;同时CSV里的JSON字段未用引号包裹,内部的逗号会被误判为CSV分隔符,导致列数不匹配。另外,你把DROP、CREATE、COPY放在同一个事务块中执行,COPY失败会触发整个事务回滚,最终导致目标表被删除。
解决步骤
1. 修复CSV数据格式
处理CSV的每一行,去掉settings字段的b'前缀和末尾的',并用双引号包裹整个JSON内容。例如原行:
1, b'{"address":null,...}'
修改为:
1,"{""address"":null,...}"
注意:JSON内部的双引号需要按CSV标准转义为"",避免被当作字段结束标记。
2. 拆分SQL执行流程
不要将DROP、CREATE、COPY放在同一条语句中执行,避免COPY失败导致表被回滚删除,分两步操作:
- 先创建目标表:
DROP TABLE IF EXISTS account_settings; CREATE TABLE account_settings ( "id" integer, "settings" super );
- 单独执行COPY命令:
COPY account_settings ("id", "settings") FROM 's3://your-bucket/your-key.csv' iam_role 'your-iam-role-arn' ignoreheader 1 CSV DELIMITER ',' QUOTE '"' ESCAPE '\';
如果JSON内部用\转义双引号,保留ESCAPE '\';如果用""转义,可省略该参数。
3. 查看详细错误日志
若COPY仍失败,查询Redshift系统表获取具体错误原因:
SELECT * FROM stl_load_errors WHERE tablename = 'account_settings' ORDER BY starttime DESC;
该表会显示出错的行号、错误类型(如JSON格式无效、列数不匹配等),帮助定位问题。
4. 备用方案:先导入为字符串再转换
如果无法修改原始CSV文件,可以先将settings列定义为字符串类型,导入后再转换为SUPER:
- 创建临时表:
CREATE TABLE temp_account_settings ( "id" integer, "settings_str" varchar(max) );
- 导入数据:
COPY temp_account_settings ("id", "settings_str") FROM 's3://your-bucket/your-key.csv' iam_role 'your-iam-role-arn' ignoreheader 1 CSV DELIMITER ',' QUOTE '"' ESCAPE '\';
- 处理数据并插入目标表:
CREATE TABLE account_settings AS SELECT id, JSON_PARSE(REPLACE(REPLACE(settings_str, 'b''', ''), '''', '')) AS settings FROM temp_account_settings;
通过REPLACE函数去掉字节串标记,再用JSON_PARSE将字符串转换为SUPER类型。
内容的提问来源于stack exchange,提问作者Raksha
相关产品推荐
相关产品推荐

