导入含引号逗号的Athena表至Postgres出现列后多余数据报错
问题根因
报错是因为你生成的CSV文件不符合PostgreSQL的CSV解析规则:
- PostgreSQL的CSV解析逻辑规定:只要字段内容包含分隔符(这里是逗号)、换行符、引号字符,整个字段必须在外层用双引号包裹。你只对JSON内部的双引号做了双写转义,但是没有给整个JSON字段加外层双引号,解析器不会把大括号包裹的JSON识别为单个字段,遇到JSON内部的逗号就会判定为新字段,最终解析出来的字段数远大于表定义的3个,就抛出"extra data after last expected column"错误。
- 举个直观的例子,你当前的JSON字段片段是
{""key1"":1,""key2"":2},解析器看到开头是{而非包裹用的双引号,就会把这段拆成{""key1"":1、""key2"":2}两个独立字段,字段数自然对不上。
修复方案
二选一即可,优先选方案1,后续导入维护更简单。
方案1:修正源文件CSV格式(推荐)
调整Athena导出逻辑,给JSON字段整体加上外层双引号即可,你之前做的JSON内部双引号双写转义是符合要求的,不需要改。
修正后的单条数据样例如下:
2022-06-05,55389e3b-3730-4cbb-85f2-d6f4de5123f4,"{""05b7ede6-c9b7-4919-86d3-015dc5e77d40"":2,""1008b57c-fe53-4e3b-b84e-257eef70ce73"":2,""886e6dce-c40d-4c58-b87d-956b61382f18"":1,""e7c67b9b-3b01-4c3b-8411-f36659600bc3"":9}"
调整完文件后,直接用你原来写的aws_s3.table_import_from_s3导入语句就能正常导入,不需要改SQL参数。
方案2:不修改源文件,用临时表中转导入(适合已生成文件、不方便重导的场景)
如果源文件已经上传到S3不好修改,可以跳过CSV解析逻辑,先按行导入再手动拆分字段:
- 先创建临时表存储原始行数据:
CREATE TEMP TABLE tmp_raw_import (raw_line TEXT);
- 以纯文本格式把S3文件导入临时表,避免逗号被误判为字段分隔符:
SELECT aws_s3.table_import_from_s3( 'tmp_raw_import', 'raw_line', '(format text)', aws_commons.create_s3_uri( 'my-bucket', 'abc/20220608_172519_00015_d684z_740d0f86-1df0-4058-9d2c-7354a328dfcb.gz', 'us-west-2' ) );
- 拆分字段并插入正式表,前两个字段按逗号切分,剩余内容全部拼接为JSON字段,替换转义的双引号后转为JSONB类型:
INSERT INTO my_table (d, id, j) SELECT arr[1]::DATE AS d, arr[2]::UUID AS id, replace(array_to_string(arr[3:], ','), '""', '"')::JSONB AS j FROM ( SELECT string_to_array(raw_line, ',') AS arr FROM tmp_raw_import ) t;
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

