Repositories
Repositories handle all database access for a model. One repository per model, one place to find all queries.
Table of contents
What they do
Instead of scattering db.session.query(User)... calls throughout routes and services, each model gets one repository. All database access for that model goes through it. This makes queries easy to find, test, and reuse.
Creating a repository
# splent_feature_notes/repositories.py
from splent_framework.repositories.BaseRepository import BaseRepository
from splent_io.splent_feature_notes.models import Notes
class NotesRepository(BaseRepository):
def __init__(self):
super().__init__(Notes)
That’s it — CRUD is inherited. Add custom queries as needed.
Real example: user repository
# splent_feature_auth/repositories.py
from splent_framework.repositories.BaseRepository import BaseRepository
from splent_io.splent_feature_auth.models import User
class UserRepository(BaseRepository):
def __init__(self):
super().__init__(User)
def create(self, commit=True, **kwargs):
password = kwargs.pop("password")
instance = self.model(**kwargs)
instance.set_password(password)
self.session.add(instance)
if commit:
self.session.commit()
else:
self.session.flush()
return instance
def get_by_email(self, email, active=True):
return self.model.query.filter_by(email=email, active=active).first()
UserRepository overrides create() to hash the password before persisting — domain logic that belongs at the data layer because it’s about how the model gets stored.
Method reference
| Method | Returns | Description |
|---|---|---|
create(commit=True, **kwargs) |
T |
Create and persist |
get_by_id(id) |
T \| None |
Find by primary key |
get_by_column(column, value) |
list[T] |
Find all matching |
get_or_404(id) |
T |
Find or HTTP 404 |
update(id, **kwargs) |
T \| None |
Update and commit |
delete(id) |
bool |
Delete by primary key |
delete_by_column(column, value) |
bool |
Delete all matching |
count() |
int |
Total rows |
Transactions
create() commits by default. Pass commit=False to flush without committing — useful for creating related objects in one transaction:
user = user_repo.create(commit=False, email="a@b.com")
profile = profile_repo.create(commit=False, user_id=user.id)
db.session.commit() # one transaction for both
Type hints
The base class is generic. Type-annotate your subclass for IDE support:
class UserRepository(BaseRepository[User]):
...