Getting hybrid property support.
This commit is contained in:
parent
b68dbfc7ae
commit
506713c748
3 changed files with 39 additions and 15 deletions
|
|
@ -1,5 +1,6 @@
|
|||
from typing import List, Tuple, Set, Dict, Optional
|
||||
from sqlalchemy import asc, desc
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm import aliased, selectinload
|
||||
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ class CRUDSpec:
|
|||
current_alias = alias
|
||||
continue
|
||||
|
||||
if isinstance(attr_obj, InstrumentedAttribute) or hasattr(attr_obj, "clauses"):
|
||||
if isinstance(attr_obj, InstrumentedAttribute) or getattr(attr_obj, "comparator", None) is not None or hasattr(attr_obj, "clauses"):
|
||||
return attr_obj, tuple(join_path) if join_path else None
|
||||
|
||||
return None, None
|
||||
|
|
@ -152,31 +153,34 @@ class CRUDSpec:
|
|||
self._rel_field_names = rel_field_names
|
||||
return root_fields, rel_field_names
|
||||
|
||||
def get_eager_loads(self, root_alias, *, fields_map: Optional[Dict[Tuple[str, ...], List[str]]] = None):
|
||||
def get_eager_loads(self, root_alias, *, fields_map=None):
|
||||
loads = []
|
||||
for path in self.eager_paths:
|
||||
current = root_alias
|
||||
loader = None
|
||||
|
||||
for idx, name in enumerate(path):
|
||||
rel_attr = getattr(current, name)
|
||||
loader = selectinload(rel_attr) if loader is None else loader.selectinload(rel_attr)
|
||||
|
||||
if loader is None:
|
||||
loader = selectinload(rel_attr)
|
||||
else:
|
||||
loader = loader.selectinload(rel_attr)
|
||||
|
||||
current = rel_attr.property.mapper.class_
|
||||
# step to target class for the next hop
|
||||
target_cls = rel_attr.property.mapper.class_
|
||||
current = target_cls
|
||||
|
||||
# if final hop and we have a fields map, narrow columns
|
||||
if fields_map and idx == len(path) - 1 and path in fields_map:
|
||||
target_cls = current
|
||||
cols = [getattr(target_cls, n) for n in fields_map[path] if hasattr(target_cls, n)]
|
||||
cols = []
|
||||
for n in fields_map[path]:
|
||||
attr = getattr(target_cls, n, None)
|
||||
# Only include real column attributes; skip hybrids/expressions
|
||||
if isinstance(attr, InstrumentedAttribute):
|
||||
cols.append(attr)
|
||||
|
||||
# Only apply load_only if we have at least one real column
|
||||
if cols:
|
||||
loader = loader.load_only(*cols)
|
||||
|
||||
if loader is not None:
|
||||
loads.append(loader)
|
||||
|
||||
return loads
|
||||
|
||||
def get_join_paths(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue