Partition Projection in AWS Athena
Use Athena partition projection to query new partitions without adding each one to the Glue Data Catalog.
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, supportingNOWwith offsets (e.g.,NOW+9HOURS).
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.
AWSTemplateFormatVersion: "2010-09-09"Description: Stack for Athena partition projection sampleResources: 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_logsDeploy the CloudFormation stack:
aws cloudformation deploy \ --template-file stack.yml \ --stack-name athena-partition-projection-sampleUploading Data
Some test data can then be uploaded to the S3 bucket:
echo '{"id": 1, "message": "hello"}' > 2021-09.jsonecho '{"id": 2, "message": "world"}' > 2021-10.jsonaws 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:
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/09The 2021/10 partition behaves the same way:
SELECT * FROM "sample"."sample_logs"WHERE year_month = '2021/10'LIMIT 10;Expected result:
2 world 2021/10Cleaning Up
Remove the resources provisioned by this example with:
aws s3 rm --recursive s3://athena-partition-projection-logsaws cloudformation delete-stack --stack-name athena-partition-projection-sampleConclusion
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.
Related posts
Querying S3 Logs with Athena and Kinesis Data Firehose
Deliver logs to S3 with Kinesis Data Firehose and query them in Athena, using custom prefixes to register partitions automatically.
Sign in with Slack Using Cognito User Pools and OIDC
Federating Cognito user pools with Slack over OIDC and wiring "Sign in with Slack" into a Next.js app with Amplify.
Deploying FastAPI on AWS Lambda with Lambda Web Adapter
Containerizing a FastAPI backend and deploying it to a single Lambda function with Lambda Web Adapter and AWS CDK.
API Gateway WebSocket: Implementing a Mock Integration
Building an API Gateway WebSocket API entirely with mock integrations, returning canned responses with no backend Lambda involved.
Uploading to S3 Through CloudFront Signed URLs
CloudFront signed URLs let you upload to S3 through a custom domain—useful when direct S3 pre-signed URLs are not an option.
