Use as_scalar()
, o 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)
Usando as_scalar()
limita las columnas y filas devueltas a 1, por lo que no puede usar todo el objeto del modelo (como query(PropertyValuation)
es una selección de todos los atributos de PropertyValuation
), pero obteniendo solo la valoración el atributo funciona.
No hay necesidad de pasarlo más tarde. Su forma actual de declarar la subconsulta está bien tal como está, ya que SQLAlchemy puede correlacionar automáticamente los objetos FROM con los de una consulta adjunta . Intenté crear modelos que representaran algo lo que tienes, y así es como funciona la consulta anterior (con saltos de línea agregados y sangría para facilitar la lectura):
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