Redshift设置GETDATE()默认列加载Parquet报列数不匹配问题咨询
核心问题根因
你碰到的两个报错完全来自Redshift对Parquet格式COPY的硬限制规则,和业务逻辑、表结构设计没有关系:
- 报错
Column mapping option argument is not supported for PARQUET based COPY:平台从设计上就不支持Parquet加载时使用文本类COPY的列映射参数,所有放在COPY命令尾部的列路径配置、列映射规则参数,都是为CSV、JSON这类非自描述格式设计的,加到Parquet的COPY语句里就会直接报错。 - 报错
Unmatched number of columns between table and file:这是Parquet COPY的默认校验逻辑导致的——如果COPY语句不做显式列声明,Redshift会强制要求Parquet文件的列数和目标表的全列数完全一致,你文件里只有18个业务列、表一共19列(带一个默认值列),自然会触发列数不匹配的校验。
正确的COPY实现方式
根本不需要修改表结构、不需要往Parquet文件里补空的LOAD_DT列,按下面的写法操作即可:
- 彻底删除所有COPY命令尾部的列映射类参数,这类写法对Parquet完全无效。
- 把Parquet文件里实际存在的18个业务列,严格参照Parquet文件内部的列顺序,写在COPY语句紧跟表名的括号列表里,绝对不要把带默认值的
LOAD_DT列放到这个列表中。
对应当前表结构的正确语句示例:COPY auto_content.DM_CONTENT( C_ID, M_ID, A_ID, A_NAME, TITLE, E_ID, START_DT, END_DT, DURATION_MS, INTERACTION_TYPE, NUM_CHAN, UPLOAD_VERSION, M_CONTENT_TYPE, T_STATUS, NUM_WORDS, METADATA_JSON, CREATED_DT, FINISHED_DT ) FROM 's3://你的存储桶路径' ACCESS_KEY_ID '你的AK' SECRET_ACCESS_KEY '你的SK' FORMAT AS PARQUET ; - 语句执行后的匹配逻辑:
- Parquet文件的18个列,按顺序依次填入列列表对应的表字段
- 未被列入列表的
LOAD_DT字段,会自动应用建表时定义的DEFAULT GETDATE()规则,自动填充当前加载时间,完全符合业务要求。
之前操作的问题溯源
你整体的流程设计没有顺序问题,把带默认值的时间列放在表最后是非常规范的设计,之前踩坑的原因是两个操作错位:
- 一开始对齐列名的时候,误用了文本格式COPY的参数写法,把列映射作为命令尾部的参数传入,触发了Parquet的兼容性报错。
- 后面尝试显式列声明的时候,大概率是列列表的顺序和Parquet文件内部的列顺序不匹配,或是列列表的数量和Parquet实际列数对不上,才触发了列数不匹配的报错。
实操注意:别信“Parquet是自描述格式,会自动按列名匹配”的通用说法,Redshift在指定显式列列表做Parquet加载时,是严格按顺序对齐的,不会走列名匹配逻辑——哪怕你Parquet里的列名和表列名一模一样,只要顺序错了就会静默填错值,写列列表时必须逐行核对Parquet文件的列顺序。
内容的提问来源于stack exchange,提问作者topplethepat
相关产品推荐
相关产品推荐

