rb-commons 0.5.21__py3-none-any.whl → 0.5.23__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.
@@ -86,6 +86,7 @@ class BaseManager(Generic[ModelType]):
86
86
  self._filtered: bool = False
87
87
  self._limit: Optional[int] = None
88
88
  self._order_by: List[Any] = []
89
+ self._joins: set[str] = set()
89
90
 
90
91
  async def _smart_commit(self, instance: Optional[ModelType] = None) -> Optional[ModelType]:
91
92
  if not self.session.in_transaction():
@@ -102,13 +103,14 @@ class BaseManager(Generic[ModelType]):
102
103
  operator = parts.pop()
103
104
 
104
105
  current: Union[Type[ModelType], InstrumentedAttribute] = self.model
105
- # walk relationships
106
+ path_parts = []
106
107
  for field in parts:
107
108
  attr = getattr(current, field, None)
108
109
  if attr is None:
109
110
  raise ValueError(f"Invalid filter field: {'.'.join(parts)}")
110
111
  if hasattr(attr, "property") and isinstance(attr.property, RelationshipProperty):
111
112
  current = attr.property.mapper.class_
113
+ path_parts.append(field)
112
114
  else:
113
115
  current = attr
114
116
 
@@ -208,17 +210,21 @@ class BaseManager(Generic[ModelType]):
208
210
 
209
211
  return self
210
212
 
211
- def filter(self, *expressions: Any, **lookups: Any) -> "BaseManager[ModelType]":
212
- """Add **AND** constraints (default behaviour)."""
213
-
213
+ def filter(self, *expressions: Any, **lookups: Any) -> "BaseManager":
214
214
  self._filtered = True
215
- for expr in expressions:
216
- if isinstance(expr, Q) or isinstance(expr, QJSON):
217
- self.filters.append(self._q_to_expr(expr))
218
- else:
219
- self.filters.append(expr)
215
+
220
216
  for k, v in lookups.items():
217
+ root = k.split("__", 1)[0]
218
+ if hasattr(self.model, root):
219
+ attr = getattr(self.model, root)
220
+ if hasattr(attr, "property") and isinstance(attr.property, RelationshipProperty):
221
+ self._joins.add(root)
222
+
221
223
  self.filters.append(self._parse_lookup(k, v))
224
+
225
+ for expr in expressions:
226
+ self.filters.append(self._q_to_expr(expr) if isinstance(expr, Q) else expr)
227
+
222
228
  return self
223
229
 
224
230
  def or_filter(self, *expressions: Any, **lookups: Any) -> "BaseManager[ModelType]":
@@ -273,9 +279,23 @@ class BaseManager(Generic[ModelType]):
273
279
  self.filters.clear()
274
280
  self._filtered = False
275
281
  self._limit = None
282
+ self._joins.clear()
276
283
 
277
284
  async def all(self, load_all_relations: bool = False):
278
285
  stmt = select(self.model)
286
+
287
+ for rel_path in self._joins:
288
+ rel_model = self.model
289
+ join_attr = None
290
+
291
+ for part in rel_path.split("__"):
292
+ join_attr = getattr(rel_model, part)
293
+ if not hasattr(join_attr, "property"):
294
+ raise ValueError(f"Invalid join path: {rel_path}")
295
+ rel_model = join_attr.property.mapper.class_
296
+
297
+ stmt = stmt.join(join_attr)
298
+
279
299
  if self.filters:
280
300
  stmt = stmt.filter(and_(*self.filters))
281
301
  if self._order_by:
@@ -467,7 +487,10 @@ class BaseManager(Generic[ModelType]):
467
487
  def sort_by(self, tokens: Sequence[str]) -> "BaseManager[ModelType]":
468
488
  """
469
489
  Dynamically apply ORDER BY clauses based on a list of "field" or "-field" tokens.
490
+ Unknown fields are collected for Python-side sorting later.
470
491
  """
492
+ self._invalid_sort_tokens = []
493
+ self._order_by = []
471
494
  model = self.model
472
495
 
473
496
  for tok in tokens:
@@ -477,8 +500,8 @@ class BaseManager(Generic[ModelType]):
477
500
  name = tok.lstrip("-")
478
501
  col = getattr(model, name, None)
479
502
  if col is None:
480
- raise InternalException(f"Cannot sort by unknown field '{name}'")
481
-
503
+ self._invalid_sort_tokens.append(tok)
504
+ continue
482
505
  self._order_by.append(direction(col))
483
506
 
484
507
  return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rb-commons
3
- Version: 0.5.21
3
+ Version: 0.5.23
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=czc2czBswfVjm51vYvMEupDGxniinAYMqkTXbiMEC7Y,18660
16
+ rb_commons/orm/managers.py,sha256=5GyVoy6QR7GfxiW77PM7Tj5xjv7DVdP9Vqx56lruwIY,19456
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.5.21.dist-info/METADATA,sha256=jgik2ADHAa9ORQNa9kd_cIafQdAKo4p1xMojbKhPJXI,6571
26
- rb_commons-0.5.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- rb_commons-0.5.21.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
- rb_commons-0.5.21.dist-info/RECORD,,
25
+ rb_commons-0.5.23.dist-info/METADATA,sha256=-qBqDrrier-vQhcQ6p8RIn0cugXYsSJW1f66NTounk8,6571
26
+ rb_commons-0.5.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ rb_commons-0.5.23.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
+ rb_commons-0.5.23.dist-info/RECORD,,