Partition Projection in AWS Athena

Partition Projection in AWS Athena

Use Athena partition projection to query new partitions without adding each one to the Glue Data Catalog.

Takahiro Iwasa
3 min read

Athena partition projection, introduced in June 2020, allows Athena to calculate partition locations instead of retrieving each partition from the Glue Data Catalog. This removes the need to run MSCK REPAIR TABLE whenever a partition is added.

Configuration

The GlueTable.TableInput.Parameters section of the CloudFormation template (lines 27–35) enables partition projection with the following properties:

  • projection.enabled: Enables partition projection.
  • projection.year_month.format: Specifies the date format for partitions.
  • projection.year_month.range: Defines the range for partitions, supporting NOW with offsets (e.g., NOW+9HOURS).
💡 Tip

The projection.year_month.range property is treated as UTC. If you intend to use a different timezone, you need to specify the time difference using a format like NOW+9HOURS.

For more details, please refer to the official documentation.

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

Deploy the CloudFormation stack:

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

Uploading Data

Some test data can then be uploaded to the S3 bucket:

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/

Verify that the files are uploaded:

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

Querying Data

Fetching data from the 2021/09 partition confirms the projection works:

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

Expected result:

1 hello 2021/09

The 2021/10 partition behaves the same way:

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

Expected result:

2 world 2021/10

Cleaning Up

Remove the resources provisioned by this example with:

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

Conclusion

With partition projection enabled on the Glue table, Athena can query newly uploaded year_month partitions without running MSCK REPAIR TABLE.

The combination of projection.enabled: true and projection.year_month.range: 2021/09,NOW makes Athena derive valid partitions from the configured range and format instead of looking them up in the Glue Data Catalog. No catalog entry needs to be added when data for a new month arrives.

The storage.location.template must match the actual S3 key layout. Because NOW is evaluated in UTC, use an explicit offset such as NOW+9HOURS when the projected range must follow a different time zone.

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

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