使用Python调用Athena查询时列带双引号且浮点列为空的问题
Athena查询结果字符串列带双引号、浮点列空的解决办法
我用boto3的start_query_execution接口执行Athena查询,代码如下:
response = client.start_query_execution( QueryString=sql, ResultConfiguration={ 'OutputLocation': f'<S3 LOCATION>', 'EncryptionConfiguration': { 'EncryptionOption': 'SSE_S3' } } )
我的Athena表包含字符串列和浮点列,查询结果存到S3的CSV用Excel打开显示正常,但记事本里字符串列都被双引号包裹。用pyathena的PandasCursor转DataFrame再生成CSV就没这问题,但速度慢很多。
更糟的是,直接在Athena里查询结果表时,字符串列全带双引号,浮点列还为空,示例如下:
| str_column1 | float_column | str_column2 |
|---|---|---|
| "example" | "example2" |
我怀疑是DDL的问题,执行SHOW CREATE TABLE得到的建表语句:
CREATE EXTERNAL TABLE `tbl` ( `str_column1` string, `float_column` float, `str_column2` string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION '<S3 LOCATION>'
试过删表后用OpenCSVSerde重建,因为有非字符串列没用;加WITH SERDEPROPERTIES ('escapeChar'='\', 'quoteChar'='"')又导致所有值挤到第一列,其余列空白。
解决方案:用LazySimpleSerDe配置正确属性
问题根源是默认SerDe的格式处理逻辑不对,换用LazySimpleSerDe(Athena原生支持的SerDe),并配置引号、转义规则,同时保证浮点列解析正常。
- 重新建表的DDL:
CREATE EXTERNAL TABLE `tbl` ( `str_column1` string, `float_column` float, `str_column2` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' WITH SERDEPROPERTIES ( 'field.delim' = ',', 'quote.delim' = '"', 'escape.delim' = '\\' ) STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION '<S3 LOCATION>'
quote.delim指定双引号为引号字符,让SerDe自动识别并去除字符串外层的多余引号escape.delim设置转义字符,避免引号内的逗号被误判为列分隔符
- 验证效果:
重建表后重新执行查询,Athena返回的结果里字符串列不会带多余双引号,浮点列能正常显示数值。S3生成的CSV用记事本打开时,只有包含特殊字符(比如逗号、换行)的字符串才会被引号包裹,普通字符串无多余引号,浮点列数值也正常。
之前尝试失败的原因
- OpenCSVSerDe对非字符串类型(比如浮点)的解析支持有限,容易出现数据丢失问题
- 之前配置SerDe属性时用了
quoteChar='"',这是HTML实体转义符,SQL里应该直接用'"'或者\'\"'来表示双引号,导致解析逻辑错误,所有值挤到第一列
内容的提问来源于stack exchange,提问作者codenoodles
相关产品推荐
相关产品推荐

