Repositories

Table of contents

  1. Introduction
  2. Adding a query
  3. Saving several records in one transaction
  4. Changing how a record is stored
  5. Reference
  6. See also

Introduction

A repository holds every database query for one model. Your services call it instead of db.session, so each model’s queries live in one place, easy to find and to test.

from splent_framework.repositories.BaseRepository import BaseRepository
from splent_io.splent_feature_notes.models import Note


class NotesRepository(BaseRepository[Note]):
    def __init__(self):
        super().__init__(Note)

That gives you the methods in the reference. The [Note] tells your editor what they return.


Adding a query

from sqlalchemy import select


class NotesRepository(BaseRepository[Note]):
    def __init__(self):
        super().__init__(Note)

    def get_by_slug(self, slug):
        return self.session.scalars(select(Note).where(Note.slug == slug)).first()

Write each query as a method. self.model is the model and self.session the shared db.session.


Saving several records in one transaction

from splent_framework.db import db

note = notes_repository.create(commit=False, title="First")
tags_repository.create(commit=False, note_id=note.id, name="draft")
db.session.commit()

create commits by default. With commit=False it only flushes, so note.id is ready and nothing is saved until you commit.


Changing how a record is stored

class NotesRepository(BaseRepository[Note]):
    def create(self, commit=True, **kwargs):
        content = kwargs.pop("content")
        note = self.model(**kwargs)
        note.set_content(content)
        self.session.add(note)
        if commit:
            self.session.commit()
        else:
            self.session.flush()
        return note

Override a method when the change is about how the model is stored. A business rule belongs in the service.


Reference

Method Returns What it does
create(commit=True, **kwargs) The record Adds it, then commits or flushes
get_by_id(id) The record or None Finds by primary key
get_or_404(id) The record Finds by primary key, or a 404
get_by_column(column, value) A list Every row whose column equals value
update(id, **kwargs) The record or None Sets the fields and commits
delete(id) bool Deletes by primary key and commits
delete_by_column(column, value) bool Deletes every matching row and commits. False when none matched
count() int How many rows there are

get_by_column and delete_by_column take a mapped column, a relationship or a hybrid property. Any other name, such as a method or a typo, raises ValueError and touches no row.


See also

  • Services, the layer that calls your repository.
  • Database, the shared db instance.

Back to top

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