不同数据结构的 Athena DDL 语句

Athena DDL statement for different data structures

我有 XML 格式的数据,我已通过胶水爬虫将其转换为 JSON 格式。问题在于在 Athena 中为 table 编写 DDL 语句,如下所示,JSON 数据中有一个 contact 属性。某处它是一个结构(单个实例),某处它是数组形式(多个实例)。我也在下面分享每种类型的 DDL 语句。

JSON 数据类型 1

"ContactList": {
               "Contact": {
                          }
                }

Athena DDL 语句

CREATE EXTERNAL TABLE IF NOT EXISTS table_name (
ContactList: struct<
             Contact: struct<
                       
             >
>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3_bucket_path'
TBLPROPERTIES ('has_encrypted_data'='false')

JSON 数据类型 2

"ContactList": {
                   "Contact": [
                              {},
                              {}
                              ]
               }

Athena DDL 语句

CREATE EXTERNAL TABLE IF NOT EXISTS table_name (
ContactList: struct<
             Contact: array < 
                      struct<
                      >
             >
>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3_bucket_path'
TBLPROPERTIES ('has_encrypted_data'='false')

我一次只能为一种情况编写 DDL 语句,而且它非常适合个别类型。我的问题是我们如何编写 DDL 语句,以便它可以满足结构或数组这两种类型。提前致谢。

您在 Athena 中解决此问题的方法是,您对 ContactList 列的 Contact 字段使用 string 类型,然后在查询中使用 JSON functions .

当您查询时,您可以这样做(假设联系人有一个“姓名”字段):

SELECT
  COALESCE(
    json_extract_scalar(ContactList.Contact, '$.name[0]'),
    json_extract_scalar(ContactList.Contact, '$.name')
  ) AS name
FROM table_name

这使用 json_extract_scalar 将字符串解析为 JSON,然后使用 JSONPath 表达式提取值。 COALESCE 选择第一个非空值,因此如果第一个 JSONPath 表达式没有产生任何值(因为 属性 不是数组),则尝试第二个。