Użyj as_scalar()
lub label()
:
subquery = (
session.query(PropertyValuation.valuation)
.filter(PropertyValuation.zip_code == Property.address_zip)
.order_by(func.abs(func.datediff(PropertyValuation.as_of, Sale.date_sold)))
.limit(1)
)
query = session.query(Sale.agent_id,
Sale.property_id,
Property.address_zip,
# `subquery.as_scalar()` or
subquery.label('back_valuation'))\
.join(Property)
Używanie as_scalar()
ogranicza zwracane kolumny i wiersze do 1, więc nie można uzyskać całego obiektu modelu za jego pomocą (jako query(PropertyValuation)
to wybór wszystkich atrybutów PropertyValuation
), ale uzyskanie tylko wyceny atrybut działa.
Nie ma potrzeby przekazywać go później. Twój obecny sposób deklarowania podzapytania jest w porządku, ponieważ SQLAlchemy może automatycznie koreluje obiekty FROM z obiektami obejmującymi zapytanie . Próbowałem stworzyć modele, które nieco reprezentują to, co masz, i oto jak działa powyższe zapytanie (z dodanymi podziałami linii i wcięciami dla czytelności):
In [10]: print(query)
SELECT sale.agent_id AS sale_agent_id,
sale.property_id AS sale_property_id,
property.address_zip AS property_address_zip,
(SELECT property_valuations.valuation
FROM property_valuations
WHERE property_valuations.zip_code = property.address_zip
ORDER BY abs(datediff(property_valuations.as_of, sale.date_sold))
LIMIT ? OFFSET ?) AS back_valuation
FROM sale
JOIN property ON property.id = sale.property_id