I have a SQLAlchemy hyrbid property similar to what's the official docs describe as a Correlated Subquery Relationship Hybrid.
Their example code looks like:
class SavingsAccount(Base):
__tablename__ = "account"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
balance = Column(Numeric(15, 5))
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
accounts = relationship("SavingsAccount", backref="owner")
@hybrid_property
def balance(self):
# I don't want to use this method
return sum(acc.balance for acc in self.accounts)
@balance.expression
def balance(cls):
# This is how I want to calculate the total balance
return (
select([func.sum(SavingsAccount.balance)])
.where(SavingsAccount.user_id == cls.id)
.label("total_balance")
)
If I'm selecting a list of multiple users, I'd like to populate the value of User.balance based on the balance.expression so the aggregation is done in SQL not in Python. However, I can't find a way to do that.
The closest I've been able to come up with is:
>>> User.query.add_columns(User.balance).all()
[(<User 1>, Decimal('10.00')), (<User 2>, Decimal('15.00')), (<User 3>, Decimal('10.00'))]
Is there another way to make an aggregation query that populates a property on my model (instead of just returning a tuple? I looked at column_property but it has fewer examples and doesn't seem powerful enough for all my use cases.