简体   繁体   English

结合两个查询,sqlalchemy

[英]Combine two queries, sqlalchemy

I'm really new to sqlalchemy (as well as sql), so please don't shoot.我对sqlalchemy(以及sql)真的很陌生,所以请不要拍。

I have two queries:我有两个疑问:

user_logins_count = self.request.db.query(
    sa.func.count(UserSession.id)
).filter(
    sa.and_(
        UserSession.user_id == user_id,
        sa.between(UserSession.date_login_session, start_date, end_date)
    )
)

and

user_questions_count = self.request.db.query(
    sa.func.count(QuestionAnswer.id).label('questions_amount')
).filter(
    sa.and_(
        QuestionAnswer.user_id == user_id,
        sa.between(QuestionAnswer.created, start_date, end_date)
    )
)

Is it possible to have a single query instead of this two?是否可以有一个查询而不是这两个?

Assuming that UserSession and QuestionAnswer are two tables in which user_id can be used as a foreign key , you can do something like假设UserSessionQuestionAnswer是两个表,其中user_id可以用作外键,您可以执行类似的操作

query(UserSession).join(QuestionAnswer, UserSession.user_id = QuestionAnswer.user_id)

to join the tables.加入表格。 If you have a join, then you can more easily query them as one unit, assuming that they both have the date information that you need.如果您有一个联接,那么您可以更轻松地将它们作为一个单元进行查询,假设它们都具有您需要的日期信息。

That said, you have some complex stuff to check and it might make more sense to do two queries and join them up than to have a complicated sub-query.也就是说,你有一些复杂的东西要检查,做两个查询并将它们连接起来可能比有一个复杂的子查询更有意义。 Or, it might make the most sense to do a union !或者,做一个union可能是最有意义的!

If you post your data structure, I can help you more specifically to build a single query that can do what you want to do.如果您发布您的数据结构,我可以更具体地帮助您构建一个可以执行您想做的事情的查询。 It's definitely possible, but it can get a bit tricky, so it would be really helpful to see an example of the data you are using and the data models you built (the classes that underlie the QuestionAnswer and UserSession tables).这绝对是可能的,但它可能会有点棘手,因此查看您正在使用的数据示例和您构建的数据模型(作为 QuestionAnswer 和 UserSession 表基础的类)将非常有帮助。

References参考

Simple subquery should do the trick:简单的子查询应该可以解决问题:

q = session.query(user_logins_count.subquery(), user_questions_count.subquery())
logins_count, questions_count = q.first()

Another, and a bit more involved, way of getting the information at the same time as you are retrieving the User instance itself would be to use hybrid_method :在检索User实例本身的同时获取信息的另一种方法是使用hybrid_method

class User(Base):
    __tablename__ = "user"

    id = Column(Integer, primary_key=True)
    name = Column(String(255))

    @hybrid_method
    def user_logins_count(self, start_date: datetime, end_date: datetime):
        return len(
            [
                _login
                for _login in self.sessions
                if start_date <= _login.date_login_session <= end_date
            ]
        )

    @classmethod
    @user_logins_count.expression
    def user_logins_count_(cls, start_date: datetime, end_date: datetime):
        return (
            select([func.count(UserSession.id).label("user_logins_count")])
            .where(UserSession.user_id == cls.id)
            .where(UserSession.date_login_session >= start_date)
            .where(UserSession.date_login_session <= end_date)
            .group_by(UserSession.user_id)
            .label("user_logins_count")
        )

In this case, the following query can be executed:在这种情况下,可以执行以下查询:

res = session.query(User, User.user_logins_count(start_date, end_date)).filter(
    User.id == user_id
)
user, logins_count = res.first()
print(user)
print(logins_count)

Adding the questions_count can be done in the same way.添加questions_count可以以相同的方式完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM