una tipos subconsultas subconsulta que ejemplos datos consultas anidadas python sqlalchemy subquery

python - tipos - subconsultas sql pdf



SQLAlchemy: subconsulta en una cláusula WHERE (2)

Recientemente comencé a usar SQLAlchemy y todavía tengo problemas para entender algunos de los conceptos.

Reducido a los elementos esenciales, tengo dos tablas como esta (esto es a través de Flask-SQLAlchemy):

class User(db.Model): __tablename__ = ''users'' user_id = db.Column(db.Integer, primary_key=True) class Posts(db.Model): __tablename__ = ''posts'' post_id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey(''users.user_id'')) post_time = db.Column(db.DateTime) user = db.relationship(''User'', backref=''posts'')

¿Cómo voy a consultar sobre una lista de usuarios y su publicación más reciente (excluyendo usuarios sin publicaciones)? Si estuviera usando SQL, haría:

SELECT [whatever] FROM posts AS p LEFT JOIN users AS u ON u.user_id = p.user_id WHERE p.post_time = (SELECT MAX(post_time) FROM posts WHERE user_id = u.user_id)

Así que sé exactamente el SQL "deseado" para obtener el efecto que quiero, pero no tengo idea de cómo expresarlo "correctamente" en SQLAlchemy.

Editar: en caso de que sea importante, estoy en SQLAlchemy 0.6.6.


Esto debería funcionar (SQL diferente, el mismo resultado):

t = Session.query( Posts.user_id, func.max(Posts.post_time).label(''max_post_time''), ).group_by(Posts.user_id).subquery(''t'') query = Session.query(User, Posts).filter(and_( User.user_id == Posts.user_id, User.user_id == t.c.user_id, Posts.post_time == t.c.max_post_time, )) for user, post in query: print user.user_id, post.post_id


la respuesta anterior funciona, pero también el sql exacto que solicitó está escrito de forma similar a la declaración real:

print s.query(Posts)./ outerjoin(Posts.user)./ filter(Posts.post_time==/ s.query( func.max(Posts.post_time) ). filter(Posts.user_id==User.user_id). correlate(User). as_scalar() )

Supongo que el "concepto" que no es necesariamente aparente es que as_scalar () es actualmente necesario para establecer una subconsulta como un "escalar" (probablemente debería suponer que del contexto contra ==).

Editar: confirmado, es un comportamiento con errores, ticket completado # 2190. En la sugerencia o versión actual 0.7.2, se llama automáticamente a as_scalar () y la consulta anterior puede ser:

print s.query(Posts)./ outerjoin(Posts.user)./ filter(Posts.post_time==/ s.query( func.max(Posts.post_time) ). filter(Posts.user_id==User.user_id). correlate(User) )