Finally got order_by fixed so sorting actually works properly with relationships and "identifier."

This commit is contained in:
Yaro Kasear 2025-08-29 09:29:12 -05:00
parent 8100d221a1
commit f47fb6b505
6 changed files with 179 additions and 18 deletions

View file

@ -74,6 +74,17 @@ def _related_predicate(Model, path_parts, op_key, value):
# wrap at this hop using the *attribute*, not the RelationshipProperty
return attr.any(pred) if rel.uselist else attr.has(pred)
def split_sort_tokens(tokens):
simple, dotted = [], []
for tok in (tokens or []):
if not tok:
continue
key = tok.lstrip("-")
if ":" in key:
key = key.split(":", 1)[0]
(dotted if "." in key else simple).append(tok)
return simple, dotted
def build_query(Model, spec: QuerySpec, eager_policy=None):
stmt = select(Model)
@ -102,11 +113,25 @@ def build_query(Model, spec: QuerySpec, eager_policy=None):
continue
stmt = stmt.where(FILTER_OPS[op_key](col, val) if op_key else (col == val))
# order_by
for key in spec.order_by:
desc_ = key.startswith("-")
col = getattr(Model, key[1:] if desc_ else key)
stmt = stmt.order_by(desc(col) if desc_ else asc(col))
simple_sorts, _ = split_sort_tokens(spec.order_by)
for token in simple_sorts:
direction = "asc"
key = token
if token.startswith("-"):
direction = "desc"
key = token[1:]
if ":" in key:
key, d = key.rsplit(":", 1)
direction = "desc" if d.lower().startswith("d") else "asc"
if "." in key:
continue
col = getattr(Model, key, None)
if col is None:
continue
stmt = stmt.order_by(desc(col) if direction == "desc" else asc(col))
if not spec.order_by and spec.page and spec.per_page:
pk_cols = inspect(Model).primary_key