Skip to content

Commit 5445879

Browse files
authored
Merge pull request #13 from sumaro2101/develop
Develop
2 parents 31cfb0b + 4591977 commit 5445879

5 files changed

Lines changed: 164 additions & 39 deletions

File tree

.env.sample

Lines changed: 0 additions & 35 deletions
This file was deleted.

api_v1/users/tasks.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ async def time_sleep_task():
1313

1414
celery_app.conf.beat_schedule = {
1515
'test-every-10-seconds': {
16-
'task': 'llm_analizer.tasks.test',
16+
'task': 'api_v1.users.tasks.time_sleep_task',
1717
'schedule': settings.celery.TEST_TIMEDELTA,
18-
'args': ('hello',)
1918
},
2019
}

config/celery/connection.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ def wrapper(*args,
4141

4242
app = Celery(__name__)
4343
app.conf.broker_url = settings.rabbit.broker_url
44-
app.conf.result_backend = 'db+' + settings.db.url
45-
app.conf.database_engine_options = {'echo': True}
4644
app.conf.timezone = settings.celery.TIMEZONE
4745
app.conf.broker_connection_retry_on_startup = True
4846
app.autodiscover_tasks(packages=['api_v1.users'])

config/dao/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .base_dao import BaseDAO
2+
3+
4+
__all__ = ('BaseDAO',)

config/dao/base_dao.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
from sqlalchemy.ext.asyncio import AsyncSession
2+
from sqlalchemy.exc import SQLAlchemyError
3+
from sqlalchemy import Select
4+
from sqlalchemy.orm import joinedload, selectinload
5+
from typing import ClassVar, Sequence
6+
7+
from config import BaseModel
8+
9+
10+
class BaseDAO:
11+
"""
12+
Базовый DAO класс для CRUD модели
13+
14+
Универсальный класс для легкого опеределения
15+
16+
CRUD модели
17+
18+
Примеры::
19+
20+
# Поиск сущности
21+
item = ModelDAO.find_item_by_args(
22+
session=session,
23+
id=3,
24+
)
25+
# Множественный поиск сущностей
26+
items = ModelDAO.find_all_items_by_args(
27+
session = session,
28+
one_to_many = (Model.tag,),
29+
name='model',
30+
)
31+
# Создание сущности
32+
item = ModelDAO.add(
33+
session,
34+
id=3,
35+
name='model',
36+
)
37+
"""
38+
model: ClassVar[BaseModel | None] = None
39+
40+
@classmethod
41+
async def find_item_by_args(cls,
42+
session: AsyncSession,
43+
one_to_many: Sequence[BaseModel] | None = None,
44+
many_to_many: Sequence[BaseModel] | None = None,
45+
**kwargs: dict[str, str | int],
46+
) -> BaseModel:
47+
"""
48+
Нахождение и возращение сущности
49+
50+
Args:
51+
session (AsyncSession): Текущая сессия
52+
53+
one_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
54+
для one_to_many
55+
которые имеют отношение например: (Product.user)
56+
57+
many_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
58+
для many_to_many
59+
которые имеют отношение например: (Product.categories)
60+
61+
Returns:
62+
BaseModel: Сущность из выборки
63+
"""
64+
stmt = struct_options_statment(
65+
model=cls.model,
66+
one_to_many=one_to_many,
67+
many_to_many=many_to_many,
68+
**kwargs,
69+
)
70+
result = await session.scalar(statement=stmt)
71+
return result
72+
73+
@classmethod
74+
async def find_all_items_by_args(cls,
75+
session: AsyncSession,
76+
one_to_many: Sequence[BaseModel] | None = None,
77+
many_to_many: Sequence[BaseModel] | None = None,
78+
**kwargs: dict[str, str | int],
79+
) -> list[BaseModel]:
80+
"""
81+
Нахождение и возращение множества сущностей
82+
83+
Args:
84+
session (AsyncSession): Текущая сессия
85+
86+
one_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
87+
для one_to_many
88+
которые имеют отношение например: (Product.user)
89+
90+
many_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
91+
для many_to_many
92+
которые имеют отношение например: (Product.categories)
93+
94+
Returns:
95+
BaseModel: Сущности из выборки
96+
"""
97+
stmt = struct_options_statment(
98+
model=cls.model,
99+
one_to_many=one_to_many,
100+
many_to_many=many_to_many,
101+
**kwargs,
102+
)
103+
result = await session.scalars(statement=stmt)
104+
return list(result)
105+
106+
@classmethod
107+
async def add(cls,
108+
session: AsyncSession,
109+
**values,
110+
) -> BaseModel:
111+
async with session.begin():
112+
instance = cls.model(**values)
113+
session.add(instance=instance)
114+
try:
115+
await session.commit()
116+
except SQLAlchemyError as ex:
117+
await session.rollback()
118+
raise ex
119+
return instance
120+
121+
122+
def struct_options_statment(model: BaseModel,
123+
one_to_many: Sequence[BaseModel] | None = None,
124+
many_to_many: Sequence[BaseModel] | None = None,
125+
**kwargs: dict[str, str | int],
126+
) -> Select:
127+
"""
128+
Струкрутирование запроса SELECT для выборки
129+
130+
Args:
131+
model (BaseModel): Модель таблицы для выборки
132+
one_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
133+
для one_to_many
134+
которые имеют отношение например: (Product.user)
135+
136+
many_to_many (Sequence[BaseModel] | None, optional): Выбранные поля
137+
для many_to_many
138+
которые имеют отношение например: (Product.categories)
139+
140+
Returns:
141+
Select: Экземпляр запроса
142+
"""
143+
if one_to_many and many_to_many:
144+
stmt = (Select(model)
145+
.filter_by(**kwargs)
146+
.options(joinedload(*one_to_many))
147+
.options(selectinload(*many_to_many)))
148+
elif one_to_many:
149+
stmt = (Select(model)
150+
.filter_by(**kwargs)
151+
.options(joinedload(*one_to_many)))
152+
elif many_to_many:
153+
stmt = (Select(model)
154+
.filter_by(**kwargs)
155+
.options(selectinload(*many_to_many)))
156+
else:
157+
stmt = (Select(model)
158+
.filter_by(**kwargs))
159+
return stmt

0 commit comments

Comments
 (0)