How to Build an In-Memory CRUD Repository Class in Python
Define a Python Repository class that stores objects in a dictionary and supports create, read, update, delete, and list operations.
Python code
40 linesclass Repository:
def __init__(self):
self._data = {}
def create(self, key, value):
self._data[key] = value
return key
def read(self, key):
return self._data.get(key)
def update(self, key, value):
if key not in self._data:
raise KeyError(f"Key '{key}' not found")
self._data[key] = value
return value
def delete(self, key):
if key not in self._data:
raise KeyError(f"Key '{key}' not found")
return self._data.pop(key)
def list_all(self):
return list(self._data.items())
if __name__ == "__main__":
repo = Repository()
repo.create("user1", {"name": "Alice", "age": 30})
repo.create("user2", {"name": "Bob", "age": 25})
print(f"Initial: {repo.list_all()}")
print(f"Read user1: {repo.read('user1')}")
repo.update("user2", {"name": "Robert", "age": 26})
print(f"After update: {repo.list_all()}")
repo.delete("user1")
print(f"After delete: {repo.list_all()}")
Output
Initial: [('user1', {'name': 'Alice', 'age': 30}), ('user2', {'name': 'Bob', 'age': 25})]
Read user1: {'name': 'Alice', 'age': 30}
After update: [('user1', {'name': 'Alice', 'age': 30}), ('user2', {'name': 'Robert', 'age': 26})]
After delete: [('user2', {'name': 'Robert', 'age': 26})]
How it works
The Repository class wraps a private dictionary _data to manage entries. The create method simply assigns a value to a key and returns the key. read uses dict.get to return None when the key is missing, avoiding a KeyError. update and delete raise a KeyError explicitly if the key does not exist, making invalid operations loud. list_all returns a list of key-value tuples, giving a snapshot of all data. Because all state lives on self, you can have multiple independent repositories without global variables.
Common mistakes
- Using `read` with direct indexing `self._data[key]` raises KeyError for missing keys; prefer `.get` for safe reads.
- Forgetting to check key existence in `update` or `delete`, leading to silent errors or unexpected behavior.
- Storing mutable objects and modifying them in place can cause side effects; consider returning copies if isolation is needed.
Variations
- Add a `clear` method to reset the repository.
- Use `defaultdict` to automatically create entries on read for certain patterns.
Real-world use cases
- Acting as a lightweight in-memory cache for frequently accessed configuration or session data in a small application.
- Serving as a stub store in unit tests when you want to isolate code that would otherwise hit a database.
- Powering a simple in-memory key-value store for a prototype or local development tool before wiring up a real datastore.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.