rb-commons 0.5.3__py3-none-any.whl → 0.5.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rb_commons/orm/managers.py +38 -7
- {rb_commons-0.5.3.dist-info → rb_commons-0.5.5.dist-info}/METADATA +1 -1
- {rb_commons-0.5.3.dist-info → rb_commons-0.5.5.dist-info}/RECORD +5 -5
- {rb_commons-0.5.3.dist-info → rb_commons-0.5.5.dist-info}/WHEEL +0 -0
- {rb_commons-0.5.3.dist-info → rb_commons-0.5.5.dist-info}/top_level.txt +0 -0
rb_commons/orm/managers.py
CHANGED
@@ -5,7 +5,7 @@ from typing import TypeVar, Type, Generic, Optional, List, Dict, Literal, Union,
|
|
5
5
|
from sqlalchemy import select, delete, update, and_, func, desc, inspect, or_
|
6
6
|
from sqlalchemy.exc import IntegrityError, SQLAlchemyError, NoResultFound
|
7
7
|
from sqlalchemy.ext.asyncio import AsyncSession
|
8
|
-
from sqlalchemy.orm import declarative_base, InstrumentedAttribute, selectinload, RelationshipProperty
|
8
|
+
from sqlalchemy.orm import declarative_base, InstrumentedAttribute, selectinload, RelationshipProperty, Load
|
9
9
|
|
10
10
|
from rb_commons.http.exceptions import NotFoundException
|
11
11
|
from rb_commons.orm.exceptions import DatabaseException, InternalException
|
@@ -135,6 +135,27 @@ class BaseManager(Generic[ModelType]):
|
|
135
135
|
)
|
136
136
|
return ~combined if q.negated else combined
|
137
137
|
|
138
|
+
def _loader_from_path(self, path: str) -> Load:
|
139
|
+
"""
|
140
|
+
Turn 'attributes.attribute.attribute_group' into
|
141
|
+
selectinload(Product.attributes)
|
142
|
+
.selectinload(Attribute.attribute)
|
143
|
+
.selectinload(ProductAttributeGroup.attribute_group)
|
144
|
+
"""
|
145
|
+
parts = path.split(".")
|
146
|
+
current_model = self.model
|
147
|
+
loader = None
|
148
|
+
|
149
|
+
for segment in parts:
|
150
|
+
attr = getattr(current_model, segment, None)
|
151
|
+
if attr is None or not hasattr(attr, "property"):
|
152
|
+
raise ValueError(f"Invalid relationship path: {path!r}")
|
153
|
+
|
154
|
+
loader = selectinload(attr) if loader is None else loader.selectinload(attr)
|
155
|
+
current_model = attr.property.mapper.class_ # step down the graph
|
156
|
+
|
157
|
+
return loader
|
158
|
+
|
138
159
|
def order_by(self, *columns: Any):
|
139
160
|
"""Collect ORDER BY clauses.
|
140
161
|
"""
|
@@ -249,12 +270,18 @@ class BaseManager(Generic[ModelType]):
|
|
249
270
|
self._reset_state()
|
250
271
|
return result.scalars().first()
|
251
272
|
|
252
|
-
|
253
|
-
async def count(self) -> int:
|
273
|
+
async def count(self) -> int | None:
|
254
274
|
self._ensure_filtered()
|
255
|
-
|
256
|
-
|
257
|
-
|
275
|
+
|
276
|
+
stmt = select(func.count(self.model.id)).select_from(self.model)
|
277
|
+
if self.filters:
|
278
|
+
stmt = stmt.where(and_(*self.filters))
|
279
|
+
|
280
|
+
try:
|
281
|
+
result = await self.session.execute(stmt)
|
282
|
+
return int(result.scalar_one())
|
283
|
+
finally:
|
284
|
+
self._reset_state()
|
258
285
|
|
259
286
|
async def paginate(self, limit=10, offset=0, load_all_relations=False):
|
260
287
|
self._ensure_filtered()
|
@@ -368,7 +395,11 @@ class BaseManager(Generic[ModelType]):
|
|
368
395
|
stmt = select(self.model).filter_by(id=pk)
|
369
396
|
if load_relations:
|
370
397
|
for rel in load_relations:
|
371
|
-
|
398
|
+
loader = (
|
399
|
+
self._loader_from_path(rel) if "." in rel
|
400
|
+
else selectinload(getattr(self.model, rel))
|
401
|
+
)
|
402
|
+
stmt = stmt.options(loader)
|
372
403
|
result = await self.session.execute(stmt)
|
373
404
|
instance = result.scalar_one_or_none()
|
374
405
|
if instance is None:
|
@@ -11,7 +11,7 @@ rb_commons/http/consul.py,sha256=Ioq72VD1jGwoC96set7n2SgxN40olzI-myA2lwKkYi4,186
|
|
11
11
|
rb_commons/http/exceptions.py,sha256=EGRMr1cRgiJ9Q2tkfANbf0c6-zzXf1CD6J3cmCaT_FA,1885
|
12
12
|
rb_commons/orm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
rb_commons/orm/exceptions.py,sha256=1aMctiEwrPjyehoXVX1l6ML5ZOhmDkmBISzlTD5ey1Y,509
|
14
|
-
rb_commons/orm/managers.py,sha256=
|
14
|
+
rb_commons/orm/managers.py,sha256=mKpsN1OrPUDxF12KyZleZNMD7vBBQ503pWclIYjGWFE,16565
|
15
15
|
rb_commons/orm/services.py,sha256=71eRcJ4TxZvzNz-hLXo12X4U7PGK54ZfbLAb27AjZi8,1589
|
16
16
|
rb_commons/permissions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
rb_commons/permissions/role_permissions.py,sha256=HL50s5RHW1nk2U3-YTESg0EDGkJDu1vN4QchcfK-L5g,988
|
@@ -20,7 +20,7 @@ rb_commons/schemes/jwt.py,sha256=F66JJDhholuOPPzlKeoC6f1TL4gXg4oRUrV5yheNpyo,167
|
|
20
20
|
rb_commons/schemes/pagination.py,sha256=8VZW1wZGJIPR9jEBUgppZUoB4uqP8ORudHkMwvEJSxg,1866
|
21
21
|
rb_commons/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
rb_commons/utils/media.py,sha256=KNY_9SdRa3Rp7d3B1tZaXkhmzVa65RcS62BYwZP1bVM,332
|
23
|
-
rb_commons-0.5.
|
24
|
-
rb_commons-0.5.
|
25
|
-
rb_commons-0.5.
|
26
|
-
rb_commons-0.5.
|
23
|
+
rb_commons-0.5.5.dist-info/METADATA,sha256=Q6QZet60caB50aSvjYzEeWzCDvftwoSEW4NH0ofmjRg,6570
|
24
|
+
rb_commons-0.5.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
25
|
+
rb_commons-0.5.5.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
|
26
|
+
rb_commons-0.5.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|