rb-commons 0.7.0__py3-none-any.whl → 0.7.1__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.
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
3
4
  import uuid
4
5
  from typing import TypeVar, Type, Generic, Optional, List, Dict, Literal, Union, Sequence, Any, Iterable
5
6
  from sqlalchemy import select, delete, update, and_, func, desc, inspect, or_, asc
@@ -250,19 +251,58 @@ class BaseManager(Generic[ModelType]):
250
251
  self._limit = value
251
252
  return self
252
253
 
253
- def _build_relation_loaders(self, model: Any, relations: Sequence[str]) -> List[Load]:
254
+ def _build_relation_loaders(
255
+ self,
256
+ model: Any,
257
+ relations: Sequence[str] | None = None
258
+ ) -> List[Load]:
254
259
  """
255
- Turn ['cat','product__tags'] into
256
- [selectinload(model.cat),
257
- selectinload(model.product).selectinload('tags')]
260
+ Given e.g. ["media", "properties.property", "properties__property"],
261
+ returns [
262
+ selectinload(Product.media),
263
+ selectinload(Product.properties).selectinload(Property.property)
264
+ ].
265
+
266
+ If `relations` is None or empty, recurse *all* relationships once (cycle-safe).
258
267
  """
259
268
  loaders: List[Load] = []
260
- for path in relations:
261
- parts = path.split("__")
262
- loader = selectinload(getattr(model, parts[0]))
263
- for sub in parts[1:]:
264
- loader = loader.selectinload(sub)
265
- loaders.append(loader)
269
+
270
+ if relations:
271
+ for path in relations:
272
+ parts = re.split(r"\.|\_\_", path)
273
+ current_model = model
274
+ loader: Load | None = None
275
+
276
+ for part in parts:
277
+ attr = getattr(current_model, part, None)
278
+ if attr is None or not hasattr(attr, "property"):
279
+ raise ValueError(f"Invalid relationship path: {path!r}")
280
+ loader = selectinload(attr) if loader is None else loader.selectinload(attr)
281
+ current_model = attr.property.mapper.class_
282
+
283
+ loaders.append(loader)
284
+
285
+ return loaders
286
+
287
+ visited = set()
288
+
289
+ def recurse(curr_model: Any, curr_loader: Load | None = None):
290
+ mapper = inspect(curr_model)
291
+ if mapper in visited:
292
+ return
293
+ visited.add(mapper)
294
+
295
+ for rel in mapper.relationships:
296
+ attr = getattr(curr_model, rel.key)
297
+ loader = (
298
+ selectinload(attr)
299
+ if curr_loader is None
300
+ else curr_loader.selectinload(attr)
301
+ )
302
+ loaders.append(loader)
303
+ recurse(rel.mapper.class_, loader)
304
+
305
+ recurse(model)
266
306
  return loaders
267
307
 
268
308
  async def _execute_query(self, stmt):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rb-commons
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Commons of project and simplified orm based on sqlalchemy.
5
5
  Home-page: https://github.com/RoboSell-organization/rb-commons
6
6
  Author: Abdulvoris
@@ -13,7 +13,7 @@ rb_commons/http/consul.py,sha256=Ioq72VD1jGwoC96set7n2SgxN40olzI-myA2lwKkYi4,186
13
13
  rb_commons/http/exceptions.py,sha256=EGRMr1cRgiJ9Q2tkfANbf0c6-zzXf1CD6J3cmCaT_FA,1885
14
14
  rb_commons/orm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  rb_commons/orm/exceptions.py,sha256=1aMctiEwrPjyehoXVX1l6ML5ZOhmDkmBISzlTD5ey1Y,509
16
- rb_commons/orm/managers.py,sha256=TIIoZzxlUGscNFj0diWdNNwsajF8ncFFF24mptjxGxU,18312
16
+ rb_commons/orm/managers.py,sha256=5ud5TWpR4D-1W9R1TYuK1MDcimFxZeJUwXTcbAqWPEM,19627
17
17
  rb_commons/orm/services.py,sha256=71eRcJ4TxZvzNz-hLXo12X4U7PGK54ZfbLAb27AjZi8,1589
18
18
  rb_commons/permissions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  rb_commons/permissions/role_permissions.py,sha256=4dV89z6ggzLqCCiFYlMp7kQVJRESu6MHpkT5ZNjLo6A,1096
@@ -22,7 +22,7 @@ rb_commons/schemes/jwt.py,sha256=ZKLJ5D3fcEmEKySjzbxEgUcza4K-oPoHr14_Z0r9Yic,249
22
22
  rb_commons/schemes/pagination.py,sha256=8VZW1wZGJIPR9jEBUgppZUoB4uqP8ORudHkMwvEJSxg,1866
23
23
  rb_commons/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  rb_commons/utils/media.py,sha256=J2Zi0J28DhcVQVzt-myNNVuzj9Msaetul53VjZtdDdc,820
25
- rb_commons-0.7.0.dist-info/METADATA,sha256=xIB-Y4RnBQGO9Y_UxBecnp_QWChADCuGmqw3SeRuARQ,6570
26
- rb_commons-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- rb_commons-0.7.0.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
- rb_commons-0.7.0.dist-info/RECORD,,
25
+ rb_commons-0.7.1.dist-info/METADATA,sha256=BW48hhEBVyZksP6lhZGyBgtGgYGW23pZSuw7QwGQ3ro,6570
26
+ rb_commons-0.7.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ rb_commons-0.7.1.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
+ rb_commons-0.7.1.dist-info/RECORD,,