Summary IconQuick Take

Method 1:

Hevo No-Code Pipeline – Best for: Business users or teams who want a simple, automated solution. Why choose this? Fastest setup, zero maintenance, and reliable real-time sync

Method 2:

Custom Code with AWS Lambda – Best for: Developers who need full control over the data flow and transformation logic. Why choose this? Maximum flexibility, but requires coding skills and ongoing maintenance.

Decide based on your unique needs:
Need custom logic or special data handling? → Build your own with AWS Lambda.
Want easy, automated, and real-time sync? → Go with Hevo.

DynamoDB has long been a trusted solution for managing NoSQL data in cloud-native environments. However, with the growing need for complex queries and ACID compliance, PostgreSQL offers a robust relational alternative. Its ability to handle sophisticated joins, transactions, and analytical workloads makes it ideal for today’s evolving business requirements.

In this blog, we’ll walk you through two simple methods to migrate DynamoDB to PostgreSQL using Hevo, both manual and automated. We’ll also highlight critical considerations for a successful migration. Let’s dive in and see how you can migrate DynamoDB to PostgreSQL to get the most of your relational data capabilities.

Prerequisite

Before you begin migrating your data from DynamoDB to PostgreSQL using either method, ensure you have the following requirements in place:

  • AWS Account Access: An active AWS account with proper permissions to access DynamoDB tables and create AWS Lambda functions (for custom code method).
  • DynamoDB Table Details: Complete information about your source DynamoDB table, including table name, primary key structure, and data schema.
  • PostgreSQL Database Setup: A running PostgreSQL instance (cloud-based or on-premises) with administrative access to create tables and insert data.
  • Database Connection Details: PostgreSQL connection parameters including hostname, port, database name, username, and password.
  • Network Connectivity: Ensure your migration environment can connect to both DynamoDB (via AWS APIs) and your PostgreSQL database.
  • Target Table Schema: Pre-designed PostgreSQL table structure that matches your DynamoDB data requirements, considering the differences between NoSQL and relational data models.
  • Backup Strategy: A reliable backup of your DynamoDB data before starting the migration process to prevent any data loss.

With these prerequisites met, you can proceed with either the no-code automated approach or the custom code implementation to migrate DynamoDB to PostgreSQL successfully.

How To Migrate DynamoDB to Postgres with Hevo

When moving data from DynamoDB (schema-less) to PostgreSQL (schema-enforced), you have to design a relational schema and flatten or transform any nested or semi-structured data to fit your Postgres tables. Here’s how you can do that easily:

Step 1: Prepare Your Amazon DynamoDB Credentials

Before you connect Hevo to your DynamoDB account, you need to obtain a few credentials. You have two options:

Option A: Create Access Credentials

  • Generate Access Keys: Log in to the AWS IAM Console, go to “Users,” select your user, and open the “Security credentials” tab.
Access credentials
Access credentials
  • Click “Create access key,” follow the prompts, and (optionally) add a description tag.
  • Save Credentials Securely: Copy and securely save both the Access Key and Secret Access Key, you won’t be able to view them again after leaving the page.
Access credentials
Access keys
  • (Optional) Download the .csv file containing your keys for backup purposes.

Option B: Generate IAM Role-Based Credentials

  • Create IAM Role: In the AWS IAM Console, create a new IAM role with the required permissions for DynamoDB access.
  • Assign Permissions: Attach a policy with the necessary DynamoDB permissions to the role.

Note Key Details: Record the Role ARN and any external ID you set, these will be needed to configure Hevo.

Step 2: Enable DynamoDB Streams

  • Enable DynamoDB Streams by selecting your table in the AWS Console, going to the “Exports and streams” tab, and turning on streams with “New and old images” selected.
  • Repeat this process for each table you want to sync
Streams
Streams
Streams

Step 3: Retrieve Your AWS Region

  • Find your AWS region by logging into the DynamoDB Console and checking the top-right corner, then make sure your DynamoDB is in a Hevo-supported region.
AWS region

Step 4: Configure the DynamoDB Connection in Hevo

  • In Hevo, go to PIPELINES, click + CREATE PIPELINE, and select DynamoDB as the source with a unique pipeline name.
  • Choose your connection method (IAM Role or Access Credentials), enter the required AWS details, and adjust advanced settings like “Load Historical Data” or “Include New Tables” if needed.
Configure source
  • Click TEST CONNECTION to verify, then TEST & CONTINUE to proceed
Configure source

Step 5: Configure and Activate PostgreSQL as a destination with Hevo

  • Create a PostgreSQL user, grant the necessary database and schema privileges, and ensure your server details are ready.
  • In Hevo, go to DESTINATIONS, click + CREATE DESTINATION, select PostgreSQL, and enter your connection info (host, port, user, password, database, schema, and any advanced settings like SSH or SSL).
  • Test the connection, then save and activate PostgreSQL as your destination.

Using Custom Code to Migrate DynamoDB to PostgreSQL

Step 1: Create an AWS Lambda Function

  • Set Up AWS Lambda:
    • Create an AWS Lambda function with Python as the runtime.
    • Assign the Lambda execution role with the necessary DynamoDB access permissions.
    • Set Lambda timeout to 15 minutes for large table migrations
    • Configure memory allocation (minimum 1GB for better performance)
  • Import Required Modules:
    • Import the necessary libraries for connecting DynamoDB to PostgreSQL:
import psycopg2
import boto3
import os
import json
import logging
from decimal import Decimal
  • Install psycopg2:
    • psycopg2 is not available by default in AWS Lambda, so create a Lambda Layer or directly include the psycopg2 files in the deployment package.
  • Set Up Logging and Error Handling:
    • Configure logging for better debugging and monitoring:
python
logger = logging.getLogger()
logger.setLevel(logging.INFO)
  • Set Up PostgreSQL Connection:
    • Store the database connection details (username, password, host, and database name) as environment variables in the Lambda configuration for security.
    • Create a connection to PostgreSQL using psycopg2:
python
def get_postgres_connection():
    try:
        connection = psycopg2.connect(
            user=os.environ['user'],
            password=os.environ['password'],
            host=os.environ['host'],
            database=os.environ['database']
        )
        return connection
    except Exception as e:
        logger.error(f"PostgreSQL connection failed: {str(e)}")
        raise

Step 2: Create PostgreSQL Table Schema

  • Define Target Table Structure:
    • Create the target table in PostgreSQL that matches your DynamoDB data:
python
def create_postgres_table(cursor):
    create_table_query = """
    CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        email VARCHAR(255) UNIQUE NOT NULL,
        name VARCHAR(255),
        age INTEGER,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

    """
    cursor.execute(create_table_query)
    logger.info("PostgreSQL table created successfully")

Step 3: Handle DynamoDB Data Types

Convert DynamoDB Data Types to PostgreSQL Compatible Types:

python
def convert_dynamodb_item(item):
    """Convert DynamoDB item to PostgreSQL compatible format"""
    converted_item = {}
    for key, value in item.items():
        if 'S' in value:  # String
            converted_item[key] = value['S']
        elif 'N' in value:  # Number
            converted_item[key] = float(value['N'])
        elif 'B' in value:  # Binary
            converted_item[key] = value['B']
        elif 'BOOL' in value:  # Boolean
            converted_item[key] = value['BOOL']
        elif 'NULL' in value:  # Null
            converted_item[key] = None
        # Add more type conversions as needed
    return converted_item

Step 4: Query DynamoDB with Pagination

Implement Pagination for Large Tables:

python
def scan_dynamodb_table(table_name):
    client = boto3.client('dynamodb')
    all_items = []
    try:
        # Initial scan
        response = client.scan(TableName=table_name)
        all_items.extend(response['Items'])
        # Handle pagination
        while 'LastEvaluatedKey' in response:
            response = client.scan(
                TableName=table_name,
                ExclusiveStartKey=response['LastEvaluatedKey']
            )
            all_items.extend(response['Items'])
            logger.info(f"Scanned {len(all_items)} items so far...")
        return all_items
    except Exception as e:
        logger.error(f"DynamoDB scan failed: {str(e)}")
        raise

Step 5: Batch Insert Data Into PostgreSQL

Implement Batch Processing for Better Performance:

python
def batch_insert_to_postgres(connection, items, batch_size=100):
    cursor = connection.cursor()
    try:
        for i in range(0, len(items), batch_size):
            batch = items[i:i + batch_size]
            # Prepare batch insert query
            postgres_insert_query = """
            INSERT INTO users(email, name, age) 
            VALUES %s
            ON CONFLICT (email) DO UPDATE SET
            name = EXCLUDED.name,
            age = EXCLUDED.age
            """
            # Convert batch items
            batch_values = []
            for item in batch:
                converted_item = convert_dynamodb_item(item)
                batch_values.append((
                    converted_item.get('email'),
                    converted_item.get('name'),
                    converted_item.get('age')
                ))

            # Execute batch insert
            psycopg2.extras.execute_values(
                cursor, postgres_insert_query, batch_values
            )
            connection.commit()
            logger.info(f"Inserted batch of {len(batch)} records")

    except Exception as e:
        connection.rollback()
        logger.error(f"Batch insert failed: {str(e)}")
        raise
    finally:
        cursor.close()

Step 6: Complete Migration Function

Main Lambda Handler with Complete Error Handling:

python
def lambda_handler(event, context):
    connection = None
    try:
        # Get PostgreSQL connection
        connection = get_postgres_connection()
        cursor = connection.cursor()
        # Create target table
        create_postgres_table(cursor)
        cursor.close()
        # Scan DynamoDB table
        table_name = event.get('table_name', 'user')
        dynamodb_items = scan_dynamodb_table(table_name)
        # Batch insert to PostgreSQL
        batch_insert_to_postgres(connection, dynamodb_items)
        return {
            'statusCode': 200,
            'body': json.dumps(f'Successfully migrated {len(dynamodb_items)} records')
        }
    except Exception as e:
        logger.error(f"Migration failed: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps(f'Migration failed: {str(e)}')
        }

    finally:
        if connection:
            connection.close()

Step 7: Testing and Validation

Validate Migration Success:

python
def validate_migration(connection, expected_count):
    cursor = connection.cursor()
    try:
        cursor.execute("SELECT COUNT(*) FROM users")
        actual_count = cursor.fetchone()[0]
        if actual_count == expected_count:
            logger.info(f"Migration validated: {actual_count} records migrated successfully")
            return True
        else:
            logger.warning(f"Count mismatch: Expected {expected_count}, Got {actual_count}")
            return False
    finally:
        cursor.close()
Migrate DynamoDB to PostgreSQL Effortlessly with Hevo

Looking to migrate DynamoDB to PostgreSQL for enhanced relational database capabilities? Hevo makes the process effortless, allowing you to easily bridge the gap between a NoSQL database and a relational one. Hevo’s no-code platform empowers teams to:

  1. Integrate data from 150+ sources(60+ free sources).
  2. Simplify data mapping and transformations using features like drag-and-drop.
  3. Easily migrate different data types like CSV, JSON, etc., with the auto-mapping feature. 

Join 2000+ happy customers like Whatfix and Thoughtspot, who’ve streamlined their data operations. See why Hevo is the #1 choice for building modern data stacks.

Move PostgreSQL Data for Free

Understanding migrating from DynamoDB to PostgreSQL

What is DynamoDB?

DynamoDB Azure Logo

Amazon DynamoDB is a fully managed NoSQL database service offered by AWS (Amazon Web Services). It is designed to provide fast and predictable performance with seamless scalability, making it suitable for applications that require low-latency data access.

What is PostgreSQL?

PostgreSQL

PostgreSQL is an open-source, general-purpose, object-relational database management system, or ORDBMS. It is widely used and provides advanced features along with standard compliance. Some of these features include complex queries, foreign keys, triggers, and views—all supporting transactional integrity with full ACID compliance.

Inherent in it is vast extensibility for custom data types, functions, and operators. Read about other databases ranked by popularity.

Migrate DynamoDB to PostgreSQL
Migrate DynamoDB to MySQL
Migrate DynamoDB to MS SQL Server

Use Cases To Transfer Your DynamoDB Data to Postgres

  • Advanced Analytics: You can run sophisticated queries and do data analysis on your DynamoDB data using Postgres’ robust data processing features to gain insights that aren’t attainable with DynamoDB alone.
  • Data Consolidation: In the event that you use DynamoDB in conjunction with several other sources, syncing to Postgres enables you to centralize your data for a comprehensive understanding of your operations and to establish a change data capture procedure.
  • Analyzing Historical Data: DynamoDB’s historical data is limited. Data sync with Postgres enables long-term data storage and longitudinal trend analysis.
  • Compliance and Data Security: Strong data security protections are offered by Postgres. Advanced data governance and compliance management are made possible by syncing DynamoDB data to Postgres, which also guarantees data security.
  • Scalability: Postgres is an excellent alternative for organizations with growing DynamoDB data since it can manage massive amounts of data without compromising speed.
  • Machine Learning and Data Science: You may use machine learning models for your data for predictive analytics, consumer segmentation, and other purposes if you have DynamoDB data in Postgres.
  • Reporting & Visualisation: Although Postgres can be connected to using DynamoDB, Tableau, PowerBI, and Looker (Google Data Studio) are examples of data visualization programs that can connect to Postgres and offer more sophisticated business intelligence capabilities. 

Conclusion

Organizations that migrate DynamoDB to PostgreSQL are offered significant advantages, including cost savings and enhanced flexibility in data management. However, performing this migration could seem like a daunting task without proper tools and skills. 

Hevo simplifies this migration process with its automated, no-code solution, which efficiently manages data integration, schema mapping, and real-time synchronization.

By leveraging Hevo, businesses can achieve a smooth and seamless migration, minimizing disruption and allowing them to focus on their core operations. Sign up for Hevo’s 14-day free trial and experience seamless data migration.

Frequently Asked Questions

1. Does DynamoDB support PostgreSQL?

DynamoDB does not support PostgreSQL. DynamoDB is a NoSQL database service, while PostgreSQL is a relational database.

2. How to Migrate Data from DynamoDB?

You can migrate data from DynamoDB by exporting it using AWS Data Pipeline or AWS Glue for ETL tasks. Alternatively, use AWS SDK or boto3 to query and export data programmatically, then load it into your target database (e.g., PostgreSQL or MySQL).

3. How to Migrate DynamoDB to RDS?

To migrate DynamoDB to RDS, export DynamoDB data using AWS Data Pipeline, AWS Glue, or a custom ETL process with boto3. Then, the data can be transformed if needed and loaded into RDS using JDBC or psycopg2 (for PostgreSQL).

Muhammad Faraz
Technical Content Writer, Hevo Data

Muhammad Faraz is an AI/ML and MLOps expert with extensive experience in cloud platforms and new technologies. With a Master's degree in Data Science, he excels in data science, machine learning, DevOps, and tech management. As an AI/ML and tech project manager, he leads projects in machine learning and IoT, contributing extensively researched technical content to solve complex problems.