我想使用 Athena 分区投影来编写对日期分区列进行过滤的查询。问题是我需要将投影的物理数据格式(S3 文件前缀)与用户查询的日期格式不同。
例如,我在 S3 中的物理数据格式将前缀存储为 URL 编码日期:s3://bucket/table_root/landing_time=yyyy-MM-dd%20HH%3Amm%3Ass.S'
但我希望用户能够使用可读日期(无 URL 编码格式)查询 Athena:
select * from table_root where landing_time='2020-01-01 12:00:00.0'
我尝试使用以下表格设置进行分区投影:
projection.landing_time.range: NOW-2YEARS,NOW
projection.landing_time.type: date
projection.landing_time.interval: 1
projection.landing_time.interval.unit: HOURS
projection.landing_time.format: yyyy-MM-dd'%20'HH'%3A00%3A00.0'
projection.enabled: true
我看到分区投影允许使用表属性进行自定义路径派生:storage.location.template: s3://bucket/table_root/a=${a}/${b}/some_static_subdirectory/${c}/
但我仍然没有看到任何方法来自定义日期列的投影格式并允许它与用于运行查询的格式不同。有没有办法做到这一点?
答案 0 :(得分:0)
java DateTimeFormatter 允许在格式中插入自定义字符串,例如,文本 The year is %20 YYYY
将被解析为类似 The year is %20 2021
的内容。您可能需要指定 landing_time=yyyy-MM-dd'%20'HH'%3A00%3A00.0'
作为格式,而不仅仅是 yyyy-MM-dd'%20'HH'%3A00%3A00.0'
答案 1 :(得分:0)
这可以通过添加额外的分区列来处理小时数并将 landing_time
更改为仅处理日期部分来解决。之后,更改 storage.location.template
以包含 URL 编码所需的 url 编码的 %20
和 %3A
值给了我想要的结果。
projection.landing_time.range: 2020-01-01,NOW
projection.landing_time.type: date
projection.landing_time.interval: 1
projection.landing_time.interval.unit: DAYS
projection.landing_time.format: yyyy-MM-dd
projection.hours.type: integer
projection.hours.range: 0,23
projection.hours.digits: 2
projection.enabled: true
storage.location.template: s3://bucket/table_root/landing_time=${landing_time}%20${hours}%3A00%3A00.0
使用分区投影的 Athena 查询现在可以采用以下格式编写:
select * from table_root where landing_time='2020-01-01' and hours=1;
select * from table_root where landing_time='2020-01-01' and hours>2 and hours<10;
与我的 S3 数据前缀匹配的正确格式将被投影到 S3。