SQLAlchemy Flask结合两个模型结果的过滤查询

4 投票
2 回答
13912 浏览
提问于 2025-04-17 18:08

我想按照用户注册的日期来排序他们的感谢帖子。

现在,我需要执行两个查询来获取两个列表,然后手动把它们合并和重新排序。一个用户可以是感谢的发送者,也可以是接收者。每个感谢帖总是有一个发送者,但可能有多个接收者。因此,我创建了两个模型,一个是感谢帖(Thank),另一个是接收感谢的用户(ThankReceivedByUser),来实现这个功能。

class Thank(db.Model):

    id = db.Column(db.Integer, primary_key = True)
    giver_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable = False)
    status = db.Column(db.SmallInteger, nullable = False) 
    date_registered = db.Column(db.DateTime, nullable = False)

class ThankReceivedByUser(db.Model):

    id = db.Column(db.Integer, primary_key = True)
    thank_id = db.Column(db.Integer, db.ForeignKey("thank.id"), nullable = False)
    receiver_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable = False)
    status = db.Column(db.SmallInteger, nullable = False) 
    date_registered = db.Column(db.DateTime, nullable = False)

如果能得到一些关于如何构建一个单一查询的建议,那就太好了。

2 个回答

7

如果我理解你的问题没错的话,你是想把一个用户给出的感谢和收到的感谢放在一个查询里。这样的话,你需要用到UNION,把两个查询合并起来,一个查询是选择用户给出的感谢,另一个查询是选择用户收到的感谢。然后你就可以对这个合并后的查询结果进行排序。下面是你的查询应该长得样子:

# user_id contains a value of some user's id.
given_q = db.session.query(Thank).filter_by(giver_id=user_id)
received_q = db.session.query(Thank).join(ThankReceivedByUser).\
    filter(ThankReceivedByUser.receiver_id == user_id)
q = given_q.union(received_q).order_by(Thank.date_registered)
8

我想出了一个解决这个问题的方法:

thanks = Thank.query\
    .join(ThanksReceivedByUser)\
    .filter(or_(Thank.giver_id == user.id, 
                ThankReceivedByUser.receiver_id == user.id))\
    .order_by(Thank.date_registered).all()

撰写回答