3

我是 AWS Athena 的新手,我正在尝试查询多个包含 JSON 文件的 S3 存储桶。我遇到了许多在文档中没有任何答案的问题(遗憾的是,他们的错误日志信息不足以尝试自己解决):

  1. 如何查询以括号命名的 JSON 字段?例如,我有一个名为“Capacity(GB)”的字段,当我尝试包含在 CREATE EXTERNAL 语句中时,我收到一个错误:
   CREATE EXTERNAL TABLE IF NOT EXISTS test-scema.test_table (
  `device`: string,
  `Capacity(GB)`: string)

您的查询有以下错误:

失败:执行错误,从 org.apache.hadoop.hive.ql.exec.DDLTask 返回代码 1。java.lang.IllegalArgumentException: 错误: : 预期在 'Capacity(GB):string>' 的位置,但找到了 '('。

  1. 我的文件位于 S3 的子文件夹中,结构如下:

    'location_name/YYYY/MM/DD/appstring/'

我想查询特定应用程序字符串的所有日期(在许多日期中)。有没有可以用来替换日期路径的“通配符”?像这样的东西:

LOCATION 's3://location_name/%/%/%/appstring/'

  1. 我是否必须使用 CREATE EXTERNAL TABLE 按原样加载原始数据,然后才对其进行查询,或者我可以添加一些内置的 WHERE 语句?具体来说,这样的事情是可能的:
CREATE EXTERNAL TABLE IF NOT EXISTS test_schema.test_table (
  field1:string,
  field2:string
  )

ROW FORMAT SERDE  'org.apache.hive.hcatalog.data.JsonSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3://folder/YYYY/MM/DD/appstring'

WHERE field2='value'

在计费方面会产生什么结果?因为现在我正在构建这个 CREATE 语句,只是为了再次在 SQL 查询中重用数据。

谢谢!

4

1 回答 1

2

1.带括号命名的JSON字段

无需创建名为Capacity(GB). 相反,使用不同的名称创建字段:

CREATE EXTERNAL TABLE test_table (
    device string,
    capacity string
)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
with serdeproperties ( 'paths'='device,Capacity(GB)')
LOCATION 's3://xxx';

如果您使用的是嵌套 JSON,那么您可以使用 Serde 的mapping属性(我在Hive Serde 处理嵌套结构的问题上看到了该属性):

CREATE external TABLE test_table (
   top string,
   inner struct<device:INT,
               capacity:INT>
   )
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
with serdeproperties
(
"mapping.capacity" = "Capacity(GB)"
)
LOCATION 's3://xxx';

这适用于以下输入:

{ "top" : "123", "inner": { "Capacity(GB)": 12, "device":2}}

2. 子文件夹

您不能使用通配符中间路径 ( s3://location_name/*/*/*/appstring/)。最接近的选项是使用分区数据,但这需要为您的目录使用不同的命名格式。

3. 创建表

您不能将语句指定WHERE为语句的一部分CREATE TABLE

如果您的目标是降低数据成本,则使用分区数据来减少扫描的文件数量或以 Parquet 等基于列的格式存储。

例如,请参阅:使用 Amazon Athena 分析 S3 中的数据

于 2017-04-09T07:49:08.597 回答