I'm trying to build a query into a model (Loan
) filtered by some criteria and joined into another model (LoanPayment
).
The first model has a one-to-many relationship with the second, and I'd like to collect an aggregate value over a column of the second model.
The models are defined like this:
class Loan(Base):
__tablename__ = 'loan'
id = Column(Integer, primary_key=True)
granted_date = Column(Date, nullable=False)
state = Column(String(50), default='GRANTED', index=True)
value = Column(Numeric(19, 10, asdecimal=True),
nullable=False, default=money.Decimal(0))
[... other columns ...]
class LoanPayout(Base):
__tablename__ = 'loan_payout'
id = Column(Integer, primary_key=True)
payment_date = Column(Date, nullable=False)
value = Column(Numeric(19, 10, asdecimal=True),
nullable=False, default=money.Decimal(0))
loan_id = Column(Integer, ForeignKey('loan.id'),
nullable=False, index=True)
loan = relationship('Loan',
backref=backref('payouts', lazy='dynamic',),
foreign_keys=[loan_id], order_by=payment_date.asc)
[... other columns ...]
I'd like to query all Loan.granted_date
records, filtering according to a certain criteria (say state='LATE'
), and also return the sum()
of values of all related payouts, grouped by loan.
I tried the following orm query:
session.query(
Loan.id,
Loan.granted_date,
func.sum(LoanPayout.principal).alias('loan_payout_total'),
).filter(
Loan.state == 'LATE',
).join(
LoanPayout
).group_by(Loan.id)
But SQLAlchemy (version 1.2.13) is rendering the following, which is not even valid SQL:
SELECT
loan.id AS loan_id,
loan.sale_date AS loan_sale_date,
loan_payout_total.sum_1 AS loan_payout_total_sum_1
FROM
sum(loan_payout.principal) AS loan_payout_total,
loan
JOIN loan_payout
ON loan.id = loan_payout.loan_id
WHERE
loan.state = %(state_1)s
GROUP BY
loan.id
The query is almost what I expect: it joins correctly the two tables, renders the sum()
column correctly and groups by the expected column.
But it puts what should have been the sum()
column with its alias in the FROM
section instead of the SELECT
section:
FROM
sum(loan_payout.principal) AS loan_payout_total,
loan
And then it puts an aliased column supposedly coming from that weird "selectable" into the SELECT
clause:
loan_payout_total.sum_1 AS loan_payout_total_sum_1
How do I get SQLAlchemy to render this query correctly, using the ORM support?