How to Mock DynamoDB with a Simple Dict Store in Python
A lightweight in-memory DynamoDB mock that stores items in a dict and supports put, get, and query-by-value operations for local testing.
Python code
33 linesimport json
from typing import Any, Dict, Optional
class MockDynamoDB:
def __init__(self) -> None:
self._store: Dict[str, Dict[str, Any]] = {}
def put_item(self, table_name: str, item: Dict[str, Any]) -> None:
key = str(item.get("id"))
if table_name not in self._store:
self._store[table_name] = {}
self._store[table_name][key] = item
def get_item(self, table_name: str, key: str) -> Optional[Dict[str, Any]]:
return self._store.get(table_name, {}).get(key)
def query_by_value(self, table_name: str, field: str, value: Any) -> list:
return [
item for item in self._store.get(table_name, {}).values()
if item.get(field) == value
]
if __name__ == "__main__":
db = MockDynamoDB()
db.put_item("users", {"id": 1, "name": "Alice", "age": 30})
db.put_item("users", {"id": 2, "name": "Bob", "age": 25})
db.put_item("users", {"id": 3, "name": "Alice", "age": 40})
print(json.dumps(db.get_item("users", "1"), indent=2))
print(json.dumps(db.query_by_value("users", "name", "Alice"), indent=2))
Output
{
"id": 1,
"name": "Alice",
"age": 30
}
[
{
"id": 1,
"name": "Alice",
"age": 30
},
{
"id": 3,
"name": "Alice",
"age": 40
}
]
How it works
The MockDynamoDB class mimics DynamoDB's core operations using plain Python dicts. put_item stores items nested under a table name, keyed by a primary id, which mirrors DynamoDB's partition key behavior. get_item does a simple nested lookup and returns None when the key or table doesn't exist, matching the real API's absence semantics. query_by_value filters all items in a table by a given field's equality, which is a stand-in for DynamoDB's more advanced query capabilities. This mock is ideal for unit tests where you need to verify application logic without provisioning a real DynamoDB table or using moto.
Common mistakes
- Using string keys inconsistently — put_item keys by `str(item.get('id'))` but calls like `get_item('users', 1)` would fail.
- Forgetting that `query_by_value` scans all items, unlike DynamoDB's indexed queries, so it's slow for large test datasets.
- Not resetting the mock between tests, leading to state leakage across test cases.
Variations
- Use `moto` library's `mock_dynamodb` decorator to simulate the full DynamoDB API.
- Add TTL or conditional put support to mock more advanced DynamoDB features.
Real-world use cases
- Unit-testing a repository layer that reads and writes user data to DynamoDB without hitting AWS.
- Running a localdev environment for a serverless app where a lightweight data store is needed for integration tests.
- Simulating DynamoDB behavior in a CI pipeline to catch logic errors before deploying to the cloud.
Sponsored
More from Cloud + Python
- Build a URL Shortener Client with Python medium
- Create a Cloud Storage Helper Class in Python easy
- Create a Data Helper Class for Beginners in Python easy
- Cross Account Role Chaining Mock Credentials in Python medium
- Exponential Backoff with Jitter for Cloud API Calls in Python medium
- Generate Mock CloudFormation Stack Events in Python easy
Keep learning
Related tutorials and quizzes for this topic.