Sorting data in DynamoDB is different from traditional SQL databases. Since DynamoDB is a NoSQL key-value and document database, sorting is only possible when certain conditions are met, primarily involving the sort key and how your query is structured.
In this guide, you'll learn:
-
How sorting works in DynamoDB
-
How to use Python and Boto3 to retrieve sorted results
-
How to simulate sorting using additional logic
Table of Contents
-
How Sorting Works in DynamoDB
-
Prerequisites
-
Creating a Table with Sort Key
-
Sorting Using
query()with Sort Key -
Sorting Order: Ascending vs Descending
-
Sorting with Filter Expressions (Limitations)
-
Sorting Without Sort Keys (Client-Side Sort)
-
Full Example
-
Tips and Best Practices
-
Common Pitfalls
-
Conclusion
1. How Sorting Works in DynamoDB
In DynamoDB, you cannot sort data arbitrarily like in SQL using ORDER BY. Sorting is only available when:
-
You use a sort key (also known as range key)
-
You use the
query()method, notscan() -
You define the sort direction using the
ScanIndexForwardparameter
⚙️ 2. Prerequisites
-
Python 3.7+
-
AWS account
-
DynamoDB table with partition and sort key (e.g.,
user_idandtimestamp) -
AWS credentials configured via
aws configure
3. Creating a Table with Sort Key
Make sure your table includes a sort key. Example schema:
-
Table name:
UserLogs -
Partition key:
user_id(String) -
Sort key:
timestamp(String or Number)
You can create this manually in the AWS Console or programmatically via Boto3.
4. Sorting Using query() with Sort Key
import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('UserLogs')
# Query and sort results in ascending order
response = table.query(
KeyConditionExpression=Key('user_id').eq('123'),
ScanIndexForward=True # Ascending (oldest to newest)
)
for item in response['Items']:
print(item)
Descending Order (Latest first)
response = table.query(
KeyConditionExpression=Key('user_id').eq('123'),
ScanIndexForward=False # Descending
)
⬆️⬇️ 5. Sorting Order: ScanIndexForward
| Parameter | Order |
|---|---|
ScanIndexForward=True |
Ascending (default) |
ScanIndexForward=False |
Descending |
⚠️ 6. Sorting with FilterExpression (Limitations)
You cannot sort by non-key attributes. FilterExpressions can filter results after the query, but not order them.
from boto3.dynamodb.conditions import Attr
response = table.query(
KeyConditionExpression=Key('user_id').eq('123'),
FilterExpression=Attr('event_type').eq('login'),
ScanIndexForward=False # Still only sorts on sort key
)
7. Sorting Without Sort Key: Client-Side Workaround
If your table doesn’t have a sort key or you want to sort by another attribute, use a scan + client-side sort:
response = table.scan()
sorted_items = sorted(response['Items'], key=lambda x: x['score'], reverse=True)
for item in sorted_items:
print(item)
⚠️ Use with caution —
scan()is expensive and slow for large datasets.
8. Full Example
import boto3
from boto3.dynamodb.conditions import Key
def get_user_logs(user_id, descending=False):
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('UserLogs')
response = table.query(
KeyConditionExpression=Key('user_id').eq(user_id),
ScanIndexForward=not descending
)
return response['Items']
# Usage
logs = get_user_logs('123', descending=True)
for log in logs:
print(log)
9. Tips and Best Practices
| Tip | Why It Matters |
|---|---|
| ✅ Use a sort key for natural ordering | Enables efficient sorting via query() |
| ✅ Design sort key with time-based values | Great for logs, feeds, events |
✅ Use ScanIndexForward=False for reverse order |
E.g., latest messages first |
❌ Avoid scan() unless absolutely needed |
It reads the entire table |
Handle pagination with LastEvaluatedKey |
Avoid losing data in large results |
10. Common Pitfalls
| Pitfall | Solution |
|---|---|
❌ Expecting SQL-like ORDER BY |
Use ScanIndexForward with sort key |
| ❌ Trying to sort by non-key attribute | Use client-side sorting (not scalable) |
❌ Using scan() on big tables |
Leads to high latency and cost |
| ❌ Forgetting sort key in schema | Sorting is impossible without it |
❌ Confusing query() and scan() behavior |
Only query() supports sort order |
✅ 11. Conclusion
Sorting in DynamoDB requires forethought in table design. The sort key is essential if you want to control the order of results. With Python and Boto3:
-
Use
ScanIndexForward=True/Falsewithquery() -
Avoid client-side sorting on large datasets
-
Always prefer
query()overscan()when sorting is needed
What’s Next?
Want to learn more about:
-
Global Secondary Indexes (GSIs) for sorting by different attributes?
-
Pagination with
query()andscan()? -
Combining sorting and filtering efficiently?