AWS Athena:使用 "folder" 名称作为分区

AWS Athena: use "folder" name as partition

我有数千个单独的 json 文件(对应一个 Table 行)存储在 s3 中,路径如下:s3://my-bucket/<date>/dataXX.json

当我在 DDL 中创建我的 table 时,是否可以按 S3 路径中的当前对数据进行分区? (或至少在新列中添加值)

谢谢

遗憾的是,Athena 不支持此功能。要使用文件夹进行分区,必须对文件夹的命名方式有要求。

例如 s3://my-bucket/{columnname}={columnvalue}/data.json

对于您的情况,如果您手动将这些分区添加到 table,您仍然可以使用分区。

例如 ALTER TABLE tablename ADD PARTITION (datecolumn='2017-01-01') location 's3://my-bucket/2017-01-01/

AWS 文档中有一些关于该主题的很好的示例。

AWS Athena Partitioning

无需手动执行此操作。设置胶水爬虫,如果路径中的所有文件夹具有相同的结构并且所有数据具有相同的架构设计,它将拾取文件夹(在前缀中)作为分区。

放置它会将分区命名为partition0。您可以进入 edit-schema 并将此分区的名称更改为最新名称或任何您喜欢的名称。

但请确保您进入胶水爬虫并在 "configuration options" select 选项下 - "Add new columns only"。否则在下一个 glue-crawler 运行 它将分区名称重置回 partition0.

你需要像下图一样给每个S3文件夹命名:

设置 Athena 后,为分区指定 dt:

之后,运行 MSCK REPAIR TABLE <your table name>; 在雅典娜

现在可以使用 storage.location.template 执行此操作。这将按您路径的某些部分进行分区。确保不要在列列表中包含新列,因为它将自动添加。您可以搜索很多选项来针对您的日期示例进行调整。我用“id”来展示我能想到的最简单的版本。

CREATE EXTERNAL TABLE `some_table`(
  `col1` bigint, 
PARTITIONED BY (
  `id` string
  )
ROW FORMAT SERDE 
  'org.openx.data.jsonserde.JsonSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
LOCATION
  's3://path/bucket/'
TBLPROPERTIES (
  'has_encrypted_data'='false',
  'projection.enabled'='true', 
  'projection.id.type' = 'injected',
  'storage.location.template'='s3://path/bucket/${id}/'
  )

官方文档:https://docs.amazonaws.cn/en_us/athena/latest/ug/partition-projection-dynamic-id-partitioning.html