AWS Athena のパーティションプロジェクション

AWS Athena のパーティションプロジェクション

Athena のパーティションプロジェクションを使い、パーティションを Glue Data Catalog へ個別に追加せずにクエリする方法を解説します。

Takahiro Iwasa
4 min read

2020 年 6 月に導入された Athena のパーティションプロジェクション を使うと、Glue Data Catalog から個々のパーティションを取得せず、Athena がパーティションの場所を計算します。新しいパーティションを追加するたびに MSCK REPAIR TABLE を実行する必要がありません。

設定

CloudFormation テンプレートの GlueTable.TableInput.Parameters セクション(27〜35 行目)で、以下のプロパティを指定してパーティションプロジェクションを有効にします。

  • projection.enabled: パーティションプロジェクションを有効にします。
  • projection.year_month.format: パーティションの日付フォーマットを指定します。
  • projection.year_month.range: パーティションの範囲を定義し、オフセット付きの NOW(例: NOW+9HOURS)にも対応します。
💡 Tip

projection.year_month.range プロパティは UTC として扱われます。別のタイムゾーンを使いたい場合は、NOW+9HOURS のような形式で時差を明示的に指定する必要があります。

詳細は公式ドキュメントを参照してください。

stack.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Stack for Athena partition projection sample
Resources:
S3:
Type: AWS::S3::Bucket
Properties:
BucketName: athena-partition-projection-logs
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
GlueDatabase:
Type: AWS::Glue::Database
Properties:
DatabaseInput:
Name: sample
CatalogId: !Ref AWS::AccountId
GlueTable:
Type: AWS::Glue::Table
Properties:
DatabaseName: !Ref GlueDatabase
CatalogId: !Ref AWS::AccountId
TableInput:
TableType: EXTERNAL_TABLE
Parameters:
classification: json
"projection.enabled": true
"projection.year_month.format": yyyy/MM
"projection.year_month.interval": 1
"projection.year_month.interval.unit": MONTHS
"projection.year_month.range": 2021/09,NOW
"projection.year_month.type": date
"storage.location.template": s3://athena-partition-projection-logs/${year_month}
StorageDescriptor:
Columns:
- Name: id
Type: int
- Name: message
Type: string
Location: !Sub s3://${S3}/
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed: false
NumberOfBuckets: 0
SerdeInfo:
SerializationLibrary: org.openx.data.jsonserde.JsonSerDe
Parameters:
paths: id,message
StoredAsSubDirectories: false
PartitionKeys:
- Name: year_month
Type: string
Retention: 0
Name: sample_logs

CloudFormation スタックをデプロイします。

Terminal window
aws cloudformation deploy \
--template-file stack.yml \
--stack-name athena-partition-projection-sample

データのアップロード

続けて、テストデータを S3 バケットにアップロードします。

Terminal window
echo '{"id": 1, "message": "hello"}' > 2021-09.json
echo '{"id": 2, "message": "world"}' > 2021-10.json
aws s3 cp 2021-09.json s3://athena-partition-projection-logs/2021/09/
aws s3 cp 2021-10.json s3://athena-partition-projection-logs/2021/10/

ファイルがアップロードされたことを確認します。

Terminal window
aws s3 ls s3://athena-partition-projection-logs/2021/

データのクエリ

2021/09 パーティションからデータを取得し、プロジェクションが機能していることを確認します。

SELECT * FROM "sample"."sample_logs"
WHERE year_month = '2021/09'
LIMIT 10;

期待される結果:

1 hello 2021/09

2021/10 パーティションも同様に動作します。

SELECT * FROM "sample"."sample_logs"
WHERE year_month = '2021/10'
LIMIT 10;

期待される結果:

2 world 2021/10

後片付け

この例で作成したリソースは、以下のコマンドで削除します。

Terminal window
aws s3 rm --recursive s3://athena-partition-projection-logs
aws cloudformation delete-stack --stack-name athena-partition-projection-sample

まとめ

Glue テーブルでパーティションプロジェクションを有効にすると、MSCK REPAIR TABLE を実行せずに、新しくアップロードした year_month パーティションを Athena からクエリできます。

projection.enabled: trueprojection.year_month.range: 2021/09,NOW を設定すると、Athena は Glue Data Catalog を参照せず、指定した範囲とフォーマットから有効なパーティションを導出します。新しい月のデータが追加されても、カタログへエントリを登録する必要はありません。

storage.location.template は、実際の S3 キーの構成と一致させる必要があります。また、NOW は UTC で評価されるため、別のタイムゾーンに範囲を合わせる場合は、NOW+9HOURS のようにオフセットを明示してください。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.