问题
Lets say there's a table "posts" which contains blog posts, and another table "favorites" which links a username to a post. Many users can favorite a post, so the relationship is one post to many favorites.
I am trying to figure out the syntax to join posts to favorites, but I only want those favorites where the user is the current user.
I want some thing like:
current_user = 'testuser'
posts.query.outerjoin(favorites, and_(posts.post_id == favorites.post_id, favorites.username == current_user)).limit(10).all()
This get me really close, except it seems like the "favorites.username == current_user" condition is basically getting ignored. This is what I am looking for in actual SQL:
SELECT *
FROM posts p
LEFT JOIN (
SELECT * FROM favorites f WHERE f.user_id = 'testuser'
) ff ON ff.post_id = p.post_id
LIMIT 10
It's also worth mentioning that I have defined the relationship on posts like:
favorites = db.relationship("favorites")
And I have defined the foreign key on favorites like this:
post_id = db.Column(db.String(255), db.ForeignKey('posts.post_id'))
How can I accomplish this in SQLAlchemy?
回答1:
Really you just need to replace the outerjoin with join, and the filter would work just fine.
Also, if your favorites table contains no additional information and only links users and posts, you should consider simply defining a `Many to Many' relationship. In the documentation examples Parent/Child would be your User/Post.
Update-1: just to answer second part of the question given your comment, the query below should give you an idea:
current_user = 2
subq = (db.session.query(favorites)
.filter(favorites.user_id == current_user).subquery('ff'))
q = (db.session.query(posts, subq.c.score)
.outerjoin(subq, subq.c.post_id == posts.post_id))
q = q.order_by(subq.c.score.desc())
for post, score in q:
print(post, score)
来源:https://stackoverflow.com/questions/27392661/sqlalchemy-left-join-using-subquery