Possible to eager load in select using hybrid expression? #10120
-
I have an ORM class derived from Example code: # stub of https://github.com/omnivector-solutions/license-manager/blob/main/backend/lm_backend/api/models/feature.py
class Feature(Base):
__tablename__ = "features"
id = Column(Integer, primary_key=True)
bookings = relationship("Booking", back_populates="feature", lazy="selectin")
@hybrid_property
def booked_total(self) -> int:
return sum(b.quantity for b in self.bookings)
@booked_total.inplace.expression
@classmethod
def _booked_total_expression(cls) -> SQLColumnExpression[int]:
return select(func.sum(Booking.quantity)).where(Booking.feature_id == cls.id).label("booked_total") # stub of https://github.com/omnivector-solutions/license-manager/blob/main/backend/lm_backend/api/models/booking.py
class Booking(Base):
__tablename__ = "bookings"
id = Column(Integer, primary_key=True)
quantity = Column(Integer, CheckConstraint("quantity>=0"), nullable=False) Now, when I execute a query # stub of https://github.com/omnivector-solutions/license-manager/blob/main/backend/lm_backend/api/cruds/generic.py
async def read_all(self, db_session: AsyncSession, force_refresh: bool = False):
stmt = select(self.model)
query = await db_session.scalars(stmt)
db_objs = list(query.all())
if force_refresh:
await gather(*(db_session.refresh(db_obj) for db_obj in db_objs))
return db_objs When I analyzed the query that's produced from the select, it does not join against The only way I have found to get the In a case like this where I know I want the Based on some investigation (see: https://groups.google.com/g/sqlalchemy/c/XQW8gxX93hU), it seems like it might be a limitation of hybrid attributes that a select can't load them into the dict of the resulting objects. Is there a way to work around this? I would really like to reap the performance gains of including the sub-select in the generated query instead of issuing a bunch of axillary queries to load the computed value. Thanks!! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
hi - a hybrid attribute, when you call it from a loaded instance, is just a python function, a method on the instance. I dont see any example use here in the code given, but if you have code that says When you say "However, if I include the hybrid attribute as a column in the select, it will do the join." that doesnt match the code illustrated because you have overall, I would be able to provide better guidance if the above fragments were worked into a self-contained MCVE that I can copy-and-paste here and run. |
Beta Was this translation helpful? Give feedback.
Here's an MCVE. See if you can modify this to show the mis-behavior you are seeing