如何用COPY命令将带单元分隔符的固定宽文件加载至Redshift表?
解决Redshift COPY加载带单元分隔符的固定宽度文件问题
问题原因
你的COPY命令存在两个关键错误:
- 错误使用DELIMITER参数:你把单元分隔符(US,\x1F)当成了字段分隔符,但实际它是记录分隔符,每条记录内部是固定宽度结构,字段间无分隔符。Redshift会把整个行按指定分隔符拆成字段,无法匹配表的列数,导致加载失败。
- IGNOREHEADER参数无效:文件头是当前行的前缀,并非单独一行,
IGNOREHEADER 1会直接忽略整个文件的唯一一行,自然加载0条数据。
解决方案
需要先预处理数据,把单元分隔符替换为换行符(让每条记录单独成行),同时剔除文件头和尾,再用FIXEDWIDTH参数解析固定宽度的列。
修正后的COPY命令
COPY table_name FROM 's3://bucketname/sample_data.dat' IAM_ROLE 'iam-role-arn' -- 替换为你的表对应列的固定宽度定义,格式:列名:宽度,用逗号分隔 FIXEDWIDTH 'col_id:1, col_name:5, col_date1:14, col_date2:14, col_flag1:2, col_flag2:2' -- SED命令预处理:去掉文件头、文件尾,将US替换为换行符 SED 's/^headeryyy //; s/Trailerzzz$//; s/\x1F/\n/g' REGION 'your-region'; -- 替换为你的S3桶所在区域,比如us-east-1
关键参数说明
FIXEDWIDTH:必须严格对应每条记录内各列的宽度,比如示例中记录的1 xyzzz 09102015075057 10062015102450 YY YY,要拆分出每个列的准确宽度(包括空格)。SED预处理:s/^headeryyy //:移除行首的文件头(注意匹配实际文件头的完整内容,包括末尾空格)s/Trailerzzz$//:移除行尾的文件尾s/\x1F/\n/g:将所有单元分隔符替换为换行符,让每条记录成为独立行
排查错误的方法
如果仍未加载数据,可查询Redshift的加载错误日志表,定位具体问题:
SELECT * FROM STL_LOAD_ERRORS WHERE filename LIKE '%sample_data.dat%';
内容的提问来源于stack exchange,提问作者user2104898
相关产品推荐
相关产品推荐

