Post Syndicated from Raju Ansari original https://aws.amazon.com/blogs/big-data/improve-dynamodb-analytics-with-aws-glue-zero-etl-schema-and-partition-controls/
You store transactional data in Amazon DynamoDB and get single-digit millisecond performance. However, when you want to run analytics, machine learning (ML), or reporting on that same data, you face a gap: your flexible, semi-structured DynamoDB schemas don’t align with the flat, columnar formats that analytics engines require. Bridging this gap typically means building and maintaining custom ETL pipelines, which adds development cost and operational overhead.
AWS Glue Zero-ETL integration removes that pipeline work. It enables replication of your DynamoDB tables to Apache Iceberg tables in Amazon Simple Storage Service (Amazon S3), then query it directly with Amazon Athena. During setup, you can configure two capabilities that will shape how replicated data looks and performs: schema unnesting flattens nested attributes into individual columns, and data partitioning organizes data so your queries scan only what they need.
In this post, you learn how to replicate Amazon DynamoDB data to Apache Iceberg tables in Amazon S3 through a zero-ETL integration. We walk through the challenges that the DynamoDB nested, schema-flexible data model introduces for analytics workloads, and show you how to configure schema unnesting and data partitioning for a sample product catalog table. We also cover how to query the replicated data in Amazon Athena using standard SQL.
Semi-structured data meets analytics
Your product catalog in DynamoDB contains items with nested attributes like product details, pricing tiers, and inventory information. A typical item looks like this:
{
"product_id": "P-1001",
"name": "Wireless Headphones",
"productdetails": {
"brand": "AudioTech",
"category": "Electronics",
"weight_kg": 0.25,
"specification": {
"color": "Black",
"storage": "128GB"
}
},
"pricing": {
"list_price": 79.99,
"discount_pct": 10
},
"created_at": 1701388800000
}
This structure supports fast transactional reads and writes. However, when you replicate this data for analytics, you face two decisions:
- You must decide whether to flatten nested maps like
productdetailsinto individual columns or preserve them as-is. - You must choose how to organize the data on disk so that queries filtering by brand or date range scan only relevant partitions.
With AWS Glue Zero-ETL, you address both decisions through configurable schema unnesting and data partitioning.
Solution overview
You replicate data from your DynamoDB table through AWS Glue Zero-ETL into Apache Iceberg tables stored in Amazon S3, then query the results with Amazon Athena. The following diagram illustrates the end-to-end architecture:
AWS Glue zero-ETL ingests data from Amazon DynamoDB, writes it in Apache Iceberg format to your Amazon S3 data lake, and makes it available for SQL queries in Amazon Athena—with no pipelines to build or maintain. With this integration, you:
- Save development time by skipping custom code and ETL job management
- Keep DynamoDB performance intact because replication doesn’t consume table’s provisioned read/write capacity
- Get data within 15 minutes of changes in the source table
- Query with standard tools because data lands in Apache Iceberg format, an open table format that AWS natively supports for high-performance analytics
During setup, you configure two output settings:
- Schema unnesting in Zero-ETL: You choose how nested attributes appear in the target. Flattening nested maps into individual columns streamlines your queries and reduces complexity.
- Data partitioning in Zero-ETL: You choose how data is organized into partitions. When you filter on a partition column, the query engine reads only matching data instead of scanning everything, cutting both query time and cost.
Schema unnesting
When you create a zero-ETL integration, you can choose one of three unnesting options. Schema unnesting transforms complex, nested DynamoDB structures into formats that analytics engines can query directly, removing post-processing transformations.
Each option changes how nested DynamoDB attributes appear in the target table. The right choice depends on your analytics tools and how consistent your DynamoDB schemas are.
Option 1: No unnesting
This option preserves the original nested structure. DynamoDB maps and lists remain as structured columns in the target.
Using the product example, the target table retains productid and value as columns to hold DynamoDB partition key and a DynamoDB record respectively.
Recommended for: Workloads where your analytics tools natively support querying nested data and you want to preserve the DynamoDB structure unchanged.
Option 2: Unnest one level
This option flattens top-level maps into individual columns. Lists remain nested.
With this option, productdetails and pricing each become separate columns.
Recommended for: Scenarios where your DynamoDB items have a consistent schema and you want to balance structure preservation with query simplicity.
Option 3: Unnest all levels (default)
This option recursively flattens nested structures using dot notation and produces the flattest schema.
For the product table, this creates columns such as productdetails.brand, productdetails.category, productdetails.specification.color , productdetails.specification.storage , pricing.list_price, and pricing.discount_pct. The pricing map flattens similarly. Each column is directly queryable without nested access patterns.
Recommended for: Analytics tools that prefer flat schemas when your DynamoDB items have a reasonably consistent structure. Note that deeply nested or highly variable schemas can produce very wide tables.
Data partitioning
You can speed up your queries and reduce costs by partitioning your replicated data. Partitioning divides data into logical segments on disk.
When you include a filter on a partition column in your query, the query engine skips irrelevant segments entirely. This behavior is called partition pruning: instead of scanning the entire dataset, the engine reads only the data that matches your filter conditions. For large tables, partition pruning can reduce both query runtime and cost significantly.
Default partitioning
If you don’t specify partition columns, AWS Glue Zero-ETL partitions data using the DynamoDB primary key with bucketing. This approach supports general-purpose queries without requiring manual configuration. For specific query patterns or performance requirements, you can define custom partitioning strategies described in the subsections that follow.
Identity partitioning
Identity partitioning uses raw column values to create partitions. You apply this strategy to low-to-medium cardinality columns such as brand, category, or AWS Region. To partition the product table by productdetails.brand and create a separate partition for each brand, use this configuration:
{
"partitionSpec": [
{
"fieldName": "productdetails.brand",
"functionSpec": "identity"
}
]
}
With this setup, AWS Glue creates one partition directory per unique brand value. When you query for a specific brand, Athena reads only that partition.
Important: Avoid identity partitioning on high-cardinality columns such as primary keys or timestamps. This creates many small partitions, which degrades both ingestion and query performance
Time-based partitioning
Time-based partitioning organizes data by timestamp at a chosen granularity: year, month, day, or hour. You apply this strategy to time-series data and time-range queries. To partition the product table by month on the created_at column, which stores epoch milliseconds, use this configuration:
{
"partitionSpec": [
{
"fieldName": "created_at",
"functionSpec": "month",
"conversionSpec": "epoch_milli"
}
]
}
The conversionSpec parameter tells AWS Glue how to interpret the source timestamp. Supported values: epoch_sec (Unix seconds), epoch_milli (Unix milliseconds), and iso (ISO 8601 format).
Note: The original column values remain unchanged. AWS Glue transforms only the partition column values to timestamp type in the target table
Multi-level partitioning
You can combine strategies for a hierarchical scheme. To partition first by month and then by brand, use this configuration:
{
"partitionSpec": [
{
"fieldName": "created_at",
"functionSpec": "month",
"conversionSpec": "epoch_milli"
},
{
"fieldName": "productdetails.brand",
"functionSpec": "identity"
}
]
}
This scheme supports efficient queries that filter by date range, brand, or both. Place higher-selectivity columns first in the hierarchy and align the scheme with your most common query patterns.
Best practices
Keep these guidelines in mind when you configure your integration:
- Avoid identity partitioning on high-cardinality columns such as primary keys, timestamps, or system-generated IDs. This leads to partition explosion and degrades performance.
- Apply only one time-based function per column. For example, don’t partition col1 by year, month, day, and hour simultaneously.
- Match
conversionSpecto your actual data format. If your timestamps are in epoch milliseconds, useepoch_milli, notepoch_secoriso. - Choose granularity based on data volume. High-volume tables benefit from finer granularity (day or hour). Lower-volume tables work well with coarser granularity (month or year).
- Account for timezone implications with ISO timestamps. AWS Glue Zero-ETL normalizes timestamp partition values to UTC.
Prerequisites
To implement the AWS Glue Zero-ETL integration with a DynamoDB source, you will need:
- An AWS account with least privilege principle
- An AWS Glue database (for example,
ddb_zero_etl_demo_db) with an Amazon S3 bucket associated as the database location (setup instructions) - AWS Glue Data Catalog settings updated with an AWS Identity and Access Management (IAM) policy that grants fine-grained access control for zero-ETL (setup instructions)
- Create an IAM role named
zetl-role, to be used by zero-ETL to access data from your DynamoDB table - A DynamoDB source table (for example,
product) configured for zero-ETL integration (setup instructions)
Walkthrough: Create the zero-ETL integration
Complete these steps to create a zero-ETL integration with DynamoDB as the source and Apache Iceberg tables in Amazon S3 as the target.
Step 1: Select the source type
- Open the AWS Glue console.
- In the navigation pane, under Data Integration and ETL, choose Zero-ETL integrations.
- Choose Create zero-ETL integration.
- Select Amazon DynamoDB as the source type, then choose Next.
[Figure 1: Selecting Amazon DynamoDB as the zero-ETL source type]
Step 2: Configure source and target
- In Source details, select your DynamoDB table (for example,
product). - In Target details:
-
- Select the current account as target.
- Choose the catalog and target database (for example,
ddb_zero_etl_demo_db). - Select the IAM role (for example,
zetl-role).
[Figure 2: Configuring source DynamoDB table and target database]
Step 3: Configure output settings
- Under Schema unnesting, select Unnest all fields.
- Under Data partitioning, select Specify custom partition keys.
- Enter the partition key (for example,
productdetails.brand) and set the function to Identity. - Choose Next.
[Figure 3: Configuring schema unnesting and partition key settings]
Step 4: Set integration details
- Optionally configure encryption and replication settings. The default refresh interval is 15 minutes.
- Enter a name for the integration (for example,
ddb-zero-etl-demo). - Choose Next.
[Figure 4: Configuring encryption and replication settings]
Step 5: Review and create
- Review your settings and choose Create and launch integration.
- The integration shows as Active within about a minute.
[Figure 5: Review and create summary]
[Figure 6: Integration active with successful status]
Query the replicated data
After the integration is active and the initial replication completes (typically 15–30 minutes), you can query the data in Amazon Athena.
Preview the replicated data
- Open the Amazon Athena console.
- In the query editor, select your target database (for example,
ddb_zero_etl_demo_db). - Run a preview query:
SELECT * FROM "ddb_zero_etl_demo_db"."product"LIMIT 10;
Verify schema unnesting
With Unnest all fields selected, nested attributes appear as individual columns with dot notation:
SELECT "productdetails.brand", "productdetails.category", "pricing.list_price"
FROM "ddb_zero_etl_demo_db"."product"
WHERE "productdetails.category" = 'Electronics';
Verify partition pruning
Queries that filter on the partition column (productdetails.brand) automatically skip irrelevant partitions:
SELECT product_id, name, "pricing.list_price"
FROM "ddb_zero_etl_demo_db"."product"
WHERE "productdetails.brand" = 'AudioTech';
[Figure 7: Athena query to retrieve the data from Apache Iceberg lakehouse]
You can verify the partition structure by navigating to the Amazon S3 bucket associated with your database. The data organizes into directories like:
[Figure 8: Amazon S3 bucket organization for the identity partition productdetails.brand]
Clean up
To avoid ongoing charges, delete the resources in this order:
- Delete the zero-ETL integration. In the AWS Glue console, navigate to Zero-ETL integrations, select your integration, and choose Delete. Existing replicated data remains in the target, but new changes stop replicating.
- Delete the replicated table. In the AWS Glue Data Catalog, navigate to Tables, select the replicated table, and delete it.
- Delete the AWS Glue database. In the Data Catalog, select the database and delete it.
- Delete the Amazon S3 data. Empty and delete the S3 bucket associated with the database.
- Delete the DynamoDB table. If you created it for this walkthrough, delete the source table.
- Delete IAM resources. Remove the IAM role and policies created for the integration.
Conclusion
You configured schema unnesting and data partitioning for a DynamoDB zero-ETL integration, replicated a product catalog table to Apache Iceberg tables in Amazon S3, and verified the results in Amazon Athena. Unnesting flattened nested attributes into directly queryable columns. Partitioning helped the query engine skip irrelevant data, reducing both query time and cost. To take your integration further, try monitoring replication lag and data freshness with Amazon CloudWatch metrics. You can also experiment with different partitioning strategies on a staging table before applying them to production workloads, testing time-based partitioning alongside identity partitioning to find the optimal scheme for your query patterns. For broader analytics coverage, query the same Iceberg tables from Amazon Redshift Spectrum or Amazon EMR alongside Athena. For more details, explore these resources:
- AWS Glue Zero-ETL integrations
- Monitoring zero-ETL integrations
- Amazon Athena documentation
- Amazon DynamoDB Developer Guide
- Apache Iceberg on AWS




















































Shaheer Mansoor is a Senior Machine Learning Engineer at AWS, where he specializes in developing cutting-edge machine learning platforms. His expertise lies in creating scalable infrastructure to support advanced AI solutions. His focus areas are MLOps, feature stores, data lakes, model hosting, and generative AI.
Anoop Kumar K M is a Data Architect at AWS with focus in the data and analytics area. He helps customers in building scalable data platforms and in their enterprise data strategy. His areas of interest are data platforms, data analytics, security, file systems and operating systems. Anoop loves to travel and enjoys reading books in the crime fiction and financial domains.
Sreenivas Nettem is a Lead Database Consultant at AWS Professional Services. He has experience working with Microsoft technologies with a specialization in SQL Server. He works closely with customers to help migrate and modernize their databases to AWS.
Mohammed Alkateb is an Engineering Manager at Amazon Redshift. Prior to joining Amazon, Mohammed had 12 years of industry experience in query optimization and database internals as an individual contributor and engineering manager. Mohammed has 18 US patents, and he has publications in research and industrial tracks of premier database conferences including EDBT, ICDE, SIGMOD and VLDB. Mohammed holds a PhD in Computer Science from The University of Vermont, and MSc and BSc degrees in Information Systems from Cairo University.
Ramchandra Anil Kulkarni is a software development engineer who has been with Amazon Redshift for over 4 years. He is driven to develop database innovations that serve AWS customers globally. Kulkarni’s long-standing tenure and dedication to the Amazon Redshift service demonstrate his deep expertise and commitment to delivering cutting-edge database solutions that empower AWS customers worldwide.
Mark Lyons is a Principal Product Manager on the Amazon Redshift team. He works on the intersection of data lakes and data warehouses. Prior to joining AWS, Mark held product leadership roles with Dremio and Vertica. He is passionate about data analytics and empowering customers to change the world with their data.
Asser Moustafa is a Principal Worldwide Specialist Solutions Architect at AWS, based in Dallas, Texas. He partners with customers worldwide, advising them on all aspects of their data architectures, migrations, and strategic data visions to help organizations adopt cloud-based solutions, maximize the value of their data assets, modernize legacy infrastructures, and implement cutting-edge capabilities like machine learning and advanced analytics. Prior to joining AWS, Asser held various data and analytics leadership roles, completing an MBA from New York University and an MS in Computer Science from Columbia University in New York. He is passionate about empowering organizations to become truly data-driven and unlock the transformative potential of their data.
Kalaiselvi Kamaraj is a Sr. Software Development Engineer with Amazon. She has worked on several projects within Redshift Query processing team and currently focusing on performance related projects for Redshift Data Lake.





















Tom Romano is a Sr. Solutions Architect for AWS World Wide Public Sector from Tampa, FL, and assists GovTech and EdTech customers as they create new solutions that are cloud native, event driven, and serverless. He is an enthusiastic Python programmer for both application development and data analytics, and is an Analytics Specialist. In his free time, Tom flies remote control model airplanes and enjoys vacationing with his family around Florida and the Caribbean.
Shane Thompson is a Sr. Solutions Architect based out of San Luis Obispo, California, working with AWS Startups. He works with customers who use AI/ML in their business model and is passionate about democratizing AI/ML so that all customers can benefit from it. In his free time, Shane loves to spend time with his family and travel around the world.
Kachi Odoemene is an Applied Scientist at AWS AI. He builds AI/ML solutions to solve business problems for AWS customers.
Taylor McNally is a Deep Learning Architect at Amazon Machine Learning Solutions Lab. He helps customers from various industries build solutions leveraging AI/ML on AWS. He enjoys a good cup of coffee, the outdoors, and time with his family and energetic dog.
Austin Welch is a Data Scientist in the Amazon ML Solutions Lab. He develops custom deep learning models to help AWS public sector customers accelerate their AI and cloud adoption. In his spare time, he enjoys reading, traveling, and jiu-jitsu.













SaiKiran Reddy Aenugu is a Data Architect in the Amazon Web Services (AWS) Data Lab. He has 10 years of experience implementing data loading, transformation, and visualization processes. SaiKiran currently helps organizations in North America to adopt modern data architectures such as data lakes and data mesh. He has experience in the retail, airline, and finance sectors.
Narendra Merla is a Data Architect in the Amazon Web Services (AWS) Data Lab. He has 12 years of experience in designing and productionalizing both real-time and batch-oriented data pipelines and building data lakes on both cloud and on-premises environments. Narendra currently helps organizations in North America to build and design robust data architectures, and has experience in the telecom and finance sectors.






































You would probably like to reuse the load query in the future to load data in from another S3 location. In that case, you can use the parameterized query by replacing the S3 URL of the as shown in the following screenshot:




Debu Panda is a Principal Product Manager at AWS, is an industry leader in analytics, application platform, and database technologies, and has more than 25 years of experience in the IT world.
Cansu Aksu is a Front End Engineer at AWS, has a several years of experience in developing user interfaces. She is detail oriented, eager to learn and passionate about delivering products and features that solve customer needs and problems
Chengyang Wang is a Frontend Engineer in Redshift Console Team. He worked on a number of new features delivered by redshift in the past 2 years. He thrives to deliver high quality products and aim to improve customer experience from UI















Sakti Mishra is a Data Lab Solutions Architect at AWS. He helps customers architect data analytics solutions, which gives them an accelerated path towards modernization initiatives. Outside of work, Sakti enjoys learning new technologies, watching movies, and travel.