fooder-api/fooder/repository/base.py

49 lines
1.4 KiB
Python

from typing import TypeVar, Generic, Type, Any, Sequence
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import (
select,
update as sa_update,
delete as sa_delete,
BinaryExpression,
)
from sqlalchemy.sql import Select
T = TypeVar("T")
class RepositoryBase(Generic[T]):
def __init__(self, model: Type[T], session: AsyncSession):
self.model = model
self.session = session
def _build_select(self, *expressions: BinaryExpression) -> Select[tuple[T]]:
stmt = select(self.model)
if expressions:
stmt = stmt.where(*expressions)
return stmt
async def get(self, *expressions: BinaryExpression) -> T | None:
stmt = self._build_select(*expressions)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
async def list(self, *expressions: BinaryExpression) -> Sequence[T]:
stmt = self._build_select(*expressions)
result = await self.session.execute(stmt)
return result.scalars().all()
async def create(self, obj: T) -> T:
self.session.add(obj)
await self.session.flush()
await self.session.refresh(obj)
return obj
async def delete(self, *expressions: BinaryExpression):
stmt = sa_delete(self.model)
if expressions:
stmt = stmt.where(*expressions)
await self.session.execute(stmt)