How to Use Condition Expression in DynamoDB for Safe Writes
In DynamoDB, use a
ConditionExpression to specify conditions that must be true for an operation like PutItem or UpdateItem to succeed. This helps prevent overwriting existing data or updating only when certain criteria are met. The condition uses attribute names and values with operators like =, attribute_exists(), or attribute_not_exists().Syntax
A ConditionExpression is a string that defines a condition for DynamoDB operations. It uses attribute names, placeholders, and functions to check item attributes.
- Attribute names: Refer to item fields, often with placeholders like
#name. - Attribute values: Use placeholders like
:valto represent values. - Functions: Common ones include
attribute_exists()andattribute_not_exists(). - Operators: Use
=,<,>,AND,ORto build conditions.
Example syntax:
plaintext
ConditionExpression = "attribute_not_exists(#pk) AND #age >= :minAge" ExpressionAttributeNames = {"#pk": "UserId", "#age": "Age"} ExpressionAttributeValues = {":minAge": {"N": "18"}}
Example
This example shows how to use a condition expression with PutItem to add a user only if the user ID does not already exist.
python
import boto3 # Create DynamoDB client client = boto3.client('dynamodb') # Define item to add item = { 'UserId': {'S': 'user123'}, 'Name': {'S': 'Alice'}, 'Age': {'N': '25'} } try: response = client.put_item( TableName='Users', Item=item, ConditionExpression='attribute_not_exists(UserId)' ) print('Item added successfully') except client.exceptions.ConditionalCheckFailedException: print('Item with this UserId already exists')
Output
Item added successfully
Common Pitfalls
Common mistakes when using condition expressions include:
- Not using
ExpressionAttributeNameswhen attribute names are reserved words or contain special characters. - Forgetting to handle
ConditionalCheckFailedException, which occurs if the condition is false. - Using incorrect syntax or operators in the condition expression.
- Confusing attribute existence functions like
attribute_exists()andattribute_not_exists().
Example of a wrong and right way:
python
# Wrong: Using reserved word 'Name' directly client.put_item( TableName='Users', Item=item, ConditionExpression='attribute_not_exists(Name)' ) # Right: Using ExpressionAttributeNames to avoid reserved word conflict client.put_item( TableName='Users', Item=item, ConditionExpression='attribute_not_exists(#nm)', ExpressionAttributeNames={'#nm': 'Name'} )
Quick Reference
| Function/Operator | Description | Example |
|---|---|---|
| attribute_exists(path) | True if attribute exists | attribute_exists(UserId) |
| attribute_not_exists(path) | True if attribute does not exist | attribute_not_exists(UserId) |
| = | Equals operator | #age = :val |
| <> | Not equals operator | #status <> :val |
| AND | Logical AND | attribute_exists(UserId) AND #age > :minAge |
| OR | Logical OR | attribute_not_exists(UserId) OR #age < :maxAge |
Key Takeaways
Use ConditionExpression to control when DynamoDB operations succeed based on item attributes.
Always handle ConditionalCheckFailedException to catch failed conditions.
Use ExpressionAttributeNames to avoid conflicts with reserved words.
Common functions include attribute_exists() and attribute_not_exists() for checking attribute presence.
Combine conditions with AND, OR, and comparison operators for precise control.