python - query - sqlalchemy yield
SQLAlchemy ORM: modifica las columnas devueltas desde una consulta (2)
Si tengo una consulta SQLAlchemy ORM:
admin_users = Session.query(User).filter_by(is_admin=True)
¿Es posible modificar las columnas devueltas por esa consulta?
Por ejemplo, para poder seleccionar solo la columna User.id
y usarla en una sub consulta:
admin_email_addresses = Session.query(EmailAddress)/
.filter(EmailAddress.user_id.in_(admin_users.select_columns(User.id))
Nota: el método .values()
no funcionará, ya que ejecuta la consulta y devuelve un iterable de resultados (por lo tanto, ex, EmailAddress.user_id.in_(admin_users.values(User.id))
realizará dos consultas, no una )
Sé que podría modificar la primera consulta para ser Session.query(User.id)
, pero me pregunto específicamente cómo podría modificar las columnas devueltas por una consulta.
Siento tu dolor por los values()
. En 0.6.5 agregué with_entities()
que es como values()
excepto que no itera:
q = q.with_entities(User.id)
Suponiendo que su Address.user_id
define una ForeignKey
, la siguiente consulta hará el trabajo más eficientemente en comparación con el operador IN
:
admin_email_addresses = session.query(EmailAddress)./
join(User).filter(User.is_admin==True)
Si no tiene un ForeignKey (aunque debería), puede especificar la condición de join
explícitamente:
admin_email_addresses = session.query(EmailAddress)./
join(User, User.id==EmailAddress.user_id).filter(User.is_admin==True)
Pero si realmente desea hacerlo con el operador in_
, aquí tiene (tenga en cuenta la subquery
):
subq = session.query(User.id).filter(User.is_admin==True).subquery()
admin_email_addresses = session.query(EmailAddress)./
filter(EmailAddress.user_id.in_(subq))