DynamoDb
Conditional Insert
Unique Key Constraint
AWS
NoSQL

How to insert to DynamoDb just if the key does not exist

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

When working with Amazon DynamoDB, a common requirement is to insert an item only if a particular key does not already exist. This is essential for ensuring data integrity in situations where duplicate entries must be avoided. DynamoDB's architecture and features, like conditional writes, transactional operations, and its use of primary keys, facilitate this functionality effectively.

Understanding DynamoDB's Architecture

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. In DynamoDB:

  • Tables are collections of items.
  • Items are collections of attributes.
  • Each item is uniquely identified by its primary key, which can either be a single-attribute partition key or a composite key consisting of a partition key and a sort key.

Key Components

  • Partition Key: A unique identifier for the item's location and uniqueness. If you're using a single-attribute key, it's the only attribute DynamoDB uses to store and retrieve the item's data.
  • Sort Key: Used as a secondary part of the primary key in composite keys to allow multiple items with the same partition key.

Ensuring Conditional Writes with DynamoDB

To insert an item only when the key does not exist, DynamoDB provides a feature known as Conditional Writes. This mechanism ensures that writes occur only if a specific condition is met. Here's how you can achieve this:

Using the PutItem API with ConditionExpression

The PutItem operation allows you to insert an item into the DynamoDB table. By leveraging the ConditionExpression parameter, you can specify a condition that must be satisfied for the operation to succeed.

Syntax and Example

python
1import boto3
2from botocore.exceptions import ClientError
3
4def put_item_if_not_exists(table_name, item):
5    dynamodb = boto3.resource('dynamodb')
6    table = dynamodb.Table(table_name)
7    
8    try:
9        response = table.put_item(
10            Item=item,
11            ConditionExpression='attribute_not_exists(PartitionKey)'
12        )
13        return response
14    except ClientError as e:
15        if e.response['Error']['Code'] == 'ConditionalCheckFailedException':
16            print("Conditional check failed: Item already exists")
17        else:
18            print("Unexpected error occurred:", e)
19
20# Example usage
21item = {
22    'PartitionKey': '12345',
23    'Attribute1': 'Value1',
24    'Attribute2': 'Value2'
25}
26
27put_item_if_not_exists('ExampleTable', item)
  • ConditionExpression: The attribute_not_exists function checks if the specified attribute (in this case, PartitionKey) does not exist. If it does exist, the operation fails with a ConditionalCheckFailedException.

Using the AWS CLI

You can also perform conditional writes using the AWS Command Line Interface (CLI). Here's an example:

bash
1aws dynamodb put-item \
2    --table-name ExampleTable \
3    --item '{"PartitionKey": {"S": "12345"}, "Attribute1": {"S": "Value1"}, "Attribute2": {"S": "Value2"}}' \
4    --condition-expression "attribute_not_exists(PartitionKey)"

Transactions for Conditional Inserts

For even more robust control, especially when dealing with multiple items, DynamoDB supports transactions. With transactional requests, you can bundle multiple operations and conditionally run them, ensuring all operations succeed or fail as a unit.

python
1def put_item_transaction_if_not_exists(table_name, item):
2    dynamodb = boto3.client('dynamodb')
3
4    try:
5        response = dynamodb.transact_write_items(
6            TransactItems=[
7                {
8                    'Put': {
9                        'TableName': table_name,
10                        'Item': item,
11                        'ConditionExpression': 'attribute_not_exists(PartitionKey)'
12                    }
13                },
14            ]
15        )
16        return response
17    except ClientError as e:
18        if e.response['Error']['Code'] == 'TransactionCanceledException':
19            print("Transaction canceled: One or more conditional checks failed")
20        else:
21            print("Unexpected error occurred:", e)

Summary Table

Here’s a summary of key points related to inserting into DynamoDB when a key does not exist:

FeatureDescription
ConditionExpressionEnsures operation succeeds only if specified criteria is met.
attribute_not_existsUsed in ConditionExpression to check the absence of an attribute.
ConditionalCheckFailedExceptionError returned when condition check fails.
TransactionsBundle multiple operations conditionally to run as a unit, preventing partial success.

Conclusions

Utilizing conditional writes, whether through ConditionExpression or transactions, allows for effective control over data insertion into DynamoDB. Such mechanisms are crucial in preventing duplicates by ensuring items are only added if corresponding keys do not exist. These practices are fundamental for maintaining data integrity in applications that rely heavily on unique data entries.

Additionally, the ability to use AWS SDK, AWS CLI, or other tooling to enforce these conditions provides flexibility based on your development needs. Understanding and leveraging these functionalities ensures robust data management in your DynamoDB implementations.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.