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]):
    ...

See also

  • Services — the layer that calls repositories
  • Database — the db instance used by repositories

Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es