问题描述
我是 athena 的新手,目前正在从 s3 读取文件并将它们显示为表格。
以下是 s3 存储桶中单个文件的外观。
sample.json
[
{
"name":"John","age":29,"salary":300
},{
"name":"Mary","age":25,"salary":500
}
]
我尝试用这些数据创建一个表,但我无法以所需的格式获取它。我想让每本字典占据一行。该表应包含三列(姓名、年龄、薪水)。
在下面尝试过,但将整个内容按原样放置在数据列下。
CREATE EXTERNAL TABLE IF NOT EXISTS test(
`data` string
)
LOCATION 's3://somelocation/'
TBLPROPERTIES ('has_encrypted_data'='false');
data
-----
[{"name":"John",...},{{"name":"Mary",...}]
引用了 this 但没有到达任何地方。
有没有一种理想的方法来做到这一点?仅供参考,每个文件中存在的 dict 数量可能会有所不同,并且根本不是固定的。因此,我正在寻找一种动态解决方案,如果只有一个 dict 并且 s3 中的每个文件中有 10 个,则该解决方案效果很好。
解决方法
您有两个选择:
- 使用带有 custom classifier 的 AWS Glue,使用 JSON 路径作为
$[*]
- 将记录保留为长 varchar(字符串),并使用 JSON functions 通过查询动态解析它。例如获取第一条记录的名称:
SELECT json_extract('[
{
"name":"John","age":29,"salary":300
},{
"name":"Mary","age":25,"salary":500
}
]','$[0].name');
或获取最后一条记录:
SELECT json_array_get('[
{
"name":"John",-1);
,
如果您基于 Json SerDe 创建一个 Athena 表,并且您希望单个 s3 对象在其中包含多行/记录,则期望每行/记录都在文件中的自己的行上,并且有没有包含所有记录的外部 JSON 数组。
如果您希望该表具有三列,分别是姓名、年龄和薪水,您需要在表 DDL 中声明这些列。 Json SerDe 会相应地找到 JSON props,如果你像我上面描述的那样重组你的文件。
如果您无法轻松重构文件以每行记录一条记录,那么您可能需要考虑对当前调用的列使用 Hive ARRAY 类型 data
,然后使用 Presto 的 UNNEST运算符将这些数组条目展平到表中。您可能希望将数据声明为 array<struct<>>
,其中结构体在其中包含名称、年龄和薪水道具。但我认为,如果您可以避免额外的嵌套层,您会过得更轻松。