You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Athena查询S3中格式特殊的JSON数组文件?

解决Athena查询S3中JSON数组文件的方案

针对S3中存储的JSON数组格式文件(只读权限,无法修改源文件),Athena默认JSON SerDe因期望每行是单个JSON对象而报错,以下是无需修改源文件的可行方案:

方案1:使用多行JSON SerDe直接解析数组

利用支持多行解析的JSON SerDe,将整个文件作为一个JSON数组读取,再通过UNNEST展开数组元素:

建表语句

CREATE EXTERNAL TABLE IF NOT EXISTS s3_json_arrays (
  data array<struct<name: string, category: string>>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
  'multiline' = 'true'
)
LOCATION 's3://你的存储桶路径/';

查询语句

SELECT 
  item.name,
  item.category
FROM s3_json_arrays
CROSS JOIN UNNEST(data) AS t(item);

原理:multiline = 'true'配置让SerDe读取整个文件作为单个JSON结构(此处为数组),UNNEST将数组拆分为独立行,即可提取所需字段。

方案2:用OpenCSVSerDe读取整文件为字符串后解析

如果方案1因SerDe兼容性问题失效,可将整个文件内容读取为单个字符串,再通过JSON函数解析数组:

建表语句

CREATE EXTERNAL TABLE IF NOT EXISTS json_raw_data (
  raw_content string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  'separatorChar' = '\0', -- 使用不存在的分隔符,确保整文件为一行
  'quoteChar' = '\b'      -- 避免引号干扰整行读取
)
LOCATION 's3://你的存储桶路径/';

查询语句

SELECT 
  json_extract_scalar(item, '$.name') AS name,
  json_extract_scalar(item, '$.category') AS category
FROM json_raw_data
CROSS JOIN UNNEST(json_parse(raw_content)) AS t(item);

原理:通过特殊分隔符让OpenCSVSerDe将整个文件内容读取为单个字符串列,json_parse将字符串转为JSON数组,UNNEST展开后提取字段。

注意事项

  • 两种方案均无需修改S3源文件,仅通过Athena表定义和查询逻辑处理
  • 若字段结构复杂,可调整struct的定义匹配实际JSON结构
  • 确保Athena权限允许创建外部表和执行相关查询

内容的提问来源于stack exchange,提问作者LLL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:25:37