-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d11ffee
commit 615c5d5
Showing
8 changed files
with
185 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
__all__ = ["AbstractSomeModuleRepository", "SomeModuleRepository"] | ||
|
||
from src.repositories.some_module.abc import AbstractSomeModuleRepository | ||
from src.repositories.some_module.repository import SomeModuleRepository |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
__all__ = ["AbstractSomeModuleRepository"] | ||
|
||
from abc import ABCMeta, abstractmethod | ||
from typing import TYPE_CHECKING | ||
|
||
if TYPE_CHECKING: | ||
# safe import during type checking stage; | ||
# we can do it as abstraction layer doesn't use any scheme | ||
from src.schemas import CreateSomeScheme, ViewSomeScheme, UpdateSomeScheme | ||
|
||
|
||
class AbstractSomeModuleRepository(metaclass=ABCMeta): | ||
# ----------------- CRUD ----------------- # | ||
@abstractmethod | ||
async def create(self, data: "CreateSomeScheme") -> "ViewSomeScheme": | ||
... | ||
|
||
@abstractmethod | ||
async def batch_create(self, data: list["CreateSomeScheme"]) -> list["ViewSomeScheme"]: | ||
... | ||
|
||
@abstractmethod | ||
async def read(self, id: int) -> "ViewSomeScheme": | ||
... | ||
|
||
@abstractmethod | ||
async def read_all(self) -> list["ViewSomeScheme"]: | ||
... | ||
|
||
@abstractmethod | ||
async def batch_read(self, ids: list[int]) -> list["ViewSomeScheme"]: | ||
... | ||
|
||
@abstractmethod | ||
async def update(self, id_: int, data: "UpdateSomeScheme"): | ||
... | ||
# ^^^^^^^^^^^^^^^^^ CRUD ^^^^^^^^^^^^^^^^^ # |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
__all__ = ["SomeModuleRepository"] | ||
|
||
from typing import Optional | ||
|
||
from sqlalchemy import select, insert, or_, update | ||
from sqlalchemy.dialects.postgresql import insert as postgres_insert | ||
from sqlalchemy.ext.asyncio import AsyncSession | ||
from sqlalchemy.sql.base import ExecutableOption | ||
|
||
from src.repositories.some_module.abc import AbstractSomeModuleRepository | ||
from src.schemas import ViewSomeScheme, CreateSomeScheme, UpdateSomeScheme | ||
from src.storages.sqlalchemy import AbstractSQLAlchemyStorage | ||
from src.storages.sqlalchemy.models import SomeModel | ||
|
||
# get_options = (selectinload(Model.some_field_raising_greenlet), ) | ||
get_options: tuple[ExecutableOption, ...] = () | ||
|
||
|
||
class SomeModuleRepository(AbstractSomeModuleRepository): | ||
storage: AbstractSQLAlchemyStorage | ||
|
||
def __init__(self, storage: AbstractSQLAlchemyStorage): | ||
self.storage = storage | ||
|
||
def _create_session(self) -> AsyncSession: | ||
return self.storage.create_session() | ||
|
||
# ----------------- CRUD ----------------- # | ||
|
||
async def create(self, data: CreateSomeScheme) -> ViewSomeScheme: | ||
async with self._create_session() as session: | ||
_insert_query = insert(SomeModel).returning(SomeModel) | ||
if get_options: | ||
_insert_query = _insert_query.options(*get_options) | ||
obj = await session.scalar(_insert_query, params=data.model_dump()) | ||
await session.commit() | ||
return ViewSomeScheme.model_validate(obj) | ||
|
||
async def batch_create(self, data: list[CreateSomeScheme]) -> list[ViewSomeScheme]: | ||
async with self._create_session() as session: | ||
if not data: | ||
return [] | ||
_insert_query = insert(SomeModel).returning(SomeModel) | ||
if get_options: | ||
_insert_query = _insert_query.options(*get_options) | ||
objs = await session.scalars(_insert_query, params=[obj.model_dump() for obj in data]) | ||
await session.commit() | ||
return [ViewSomeScheme.model_validate(obj) for obj in objs] | ||
|
||
async def read(self, id: int) -> ViewSomeScheme: | ||
async with self._create_session() as session: | ||
q = select(SomeModel).where(SomeModel.id == id) | ||
if get_options: | ||
q = q.options(*get_options) | ||
obj = await session.scalar(q) | ||
|
||
if obj: | ||
return ViewSomeScheme.model_validate(obj) | ||
|
||
async def read_all(self) -> list[ViewSomeScheme]: | ||
async with self._create_session() as session: | ||
q = select(SomeModel) | ||
if get_options: | ||
q = q.options(*get_options) | ||
objs = await session.scalars(q) | ||
return [ViewSomeScheme.model_validate(obj) for obj in objs] | ||
|
||
async def batch_read(self, ids: list[int]) -> list[ViewSomeScheme]: | ||
async with self._create_session() as session: | ||
if not ids: | ||
return [] | ||
|
||
q = select(SomeModel).where( | ||
or_( | ||
*[SomeModel.id == id for id in ids], | ||
) | ||
) | ||
|
||
if get_options: | ||
q = q.options(*get_options) | ||
objs = await session.scalars(q) | ||
|
||
return [ViewSomeScheme.model_validate(obj) for obj in objs] | ||
|
||
async def update(self, id_: int, data: UpdateSomeScheme): | ||
async with self._create_session() as session: | ||
q = ( | ||
update(SomeModel) | ||
.where(SomeModel.id == id_) | ||
.values(**data.model_dump()) | ||
.returning(SomeModel) | ||
) | ||
|
||
if get_options: | ||
q = q.options(*get_options) | ||
|
||
obj = await session.scalar(q) | ||
await session.commit() | ||
|
||
if obj: | ||
return ViewSomeScheme.model_validate(obj) | ||
|
||
# ^^^^^^^^^^^^^^^^^ CRUD ^^^^^^^^^^^^^^^^^ # |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
# fmt: off | ||
__all__ = [ | ||
"CreateSomeSchemeInSingle", "ViewSomeSchemeInSingle", "UpdateSomeSchemeInSingle", | ||
"CreateSomeScheme", "ViewSomeScheme", "UpdateSomeScheme", | ||
] | ||
|
||
# fmt: on | ||
|
||
from src.schemas.some_scheme_in_plural import ( | ||
CreateSomeSchemeInSingle, | ||
ViewSomeSchemeInSingle, | ||
UpdateSomeSchemeInSingle, | ||
from src.schemas.some_scheme import ( | ||
CreateSomeScheme, | ||
ViewSomeScheme, | ||
UpdateSomeScheme, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
__all__ = [ | ||
"CreateSomeScheme", | ||
"ViewSomeScheme", | ||
"UpdateSomeScheme", | ||
] | ||
|
||
from pydantic import BaseModel, ConfigDict | ||
|
||
|
||
class CreateSomeScheme(BaseModel): | ||
... | ||
|
||
|
||
class ViewSomeScheme(BaseModel): | ||
model_config = ConfigDict( | ||
from_attributes=True, | ||
) | ||
|
||
|
||
class UpdateSomeScheme(BaseModel): | ||
... | ||
|
||
# Note: if some relation is needed, add it here | ||
# from src.schemas.some_scheme2_in_plural import ViewSomeScheme2InPlural | ||
# ViewSomeSchemeInSingle.model_rebuild() |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters