如何在 AWS athena

问题描述

我是 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<>>,其中结构体在其中包含名称、年龄和薪水道具。但我认为,如果您可以避免额外的嵌套层,您会过得更轻松。