Implement task API with input validation; implement error handling; refactoring
This commit is contained in:
parent
19d264a03b
commit
50aff05614
24 changed files with 612 additions and 131 deletions
94
tofu_api/repositories/base_repository.py
Normal file
94
tofu_api/repositories/base_repository.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
__all__ = [
|
||||
'BaseRepository',
|
||||
'T_Model',
|
||||
]
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Generic, Optional, Type, TypeVar
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from tofu_api.models import BaseModel
|
||||
from .exceptions import ObjectNotFoundException
|
||||
|
||||
T_Model = TypeVar('T_Model', bound=BaseModel)
|
||||
|
||||
|
||||
class BaseRepository(Generic[T_Model], ABC):
|
||||
"""
|
||||
Base class for repositories.
|
||||
"""
|
||||
|
||||
# Database session
|
||||
session: Session
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def model_cls(self) -> Type[T_Model]:
|
||||
"""
|
||||
Set this to the model class.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def __init__(self, *, session: Session):
|
||||
self.session = session
|
||||
|
||||
@staticmethod
|
||||
def _or_raise(resource: Optional[T_Model], exception_msg: Optional[str] = None) -> T_Model:
|
||||
if resource is None:
|
||||
raise ObjectNotFoundException(exception_msg)
|
||||
return resource
|
||||
|
||||
def fetch_by_id(self, resource_id: int) -> T_Model:
|
||||
"""
|
||||
Fetches a resource by ID.
|
||||
|
||||
Raises an ObjectNotFoundException if no resource with the ID was found.
|
||||
"""
|
||||
resource = self.session.get(self.model_cls, resource_id)
|
||||
return self._or_raise(resource, f'Resource with ID {resource_id} was not found.')
|
||||
|
||||
def fetch_all(self) -> list[T_Model]:
|
||||
"""
|
||||
Fetches all resources of the repository type.
|
||||
"""
|
||||
return self.session.scalars(
|
||||
select(self.model_cls)
|
||||
).all()
|
||||
|
||||
def commit_session(self) -> None:
|
||||
"""
|
||||
Commits the current database session.
|
||||
"""
|
||||
self.commit_session()
|
||||
|
||||
def rollback_session(self) -> None:
|
||||
"""
|
||||
Rolls back the current database session.
|
||||
"""
|
||||
self.rollback_session()
|
||||
|
||||
def save_resource(self, *resources: T_Model, commit: bool = True) -> None:
|
||||
"""
|
||||
Saves one or multiple resources to the database by adding them to the session and committing the session.
|
||||
Set `commit` to False to skip committing (the session will still be flushed, though).
|
||||
"""
|
||||
for resource in resources:
|
||||
self.session.add(resource)
|
||||
self.session.flush()
|
||||
|
||||
if commit:
|
||||
self.session.commit()
|
||||
|
||||
def delete_resource(self, *resources: T_Model, commit: bool = True) -> None:
|
||||
"""
|
||||
Deletes one or multiple resources from the database.
|
||||
Set `commit` to False to skip committing (the session will still be flushed, though).
|
||||
"""
|
||||
for resource in resources:
|
||||
self.session.delete(resource)
|
||||
self.session.flush()
|
||||
|
||||
if commit:
|
||||
self.session.commit()
|
||||
Loading…
Add table
Add a link
Reference in a new issue