简体   繁体   中英

sqlalchemy - How to select count from a union query

My goal is that I have two tables, each describes a relationship between a user and either a "team" or "company"

If there are any rows that says "admin" in the tables for the userid, then I want to know that, otherwise if no rows then i need to know that as well.

What I have so far is as follows (UserTeamLink and UserCompanyLink) are Orm tabels.

obj = UserTeamLink
q1 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q1) ; q1.all()
obj = UserCompanyLink
q2 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q2) ; q2.all()

my_union = q1.union_all(q2)
query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)
query.all()

however, the line "query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)" breaks with:

AttributeError: 'BaseQuery' object has no attribute 'c'

The entire output is as follows:

>>> obj = UserTeamLink
>>> q1 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q1) ; q1.all()
'SELECT count(user_team.type) AS cnt \nFROM user_team \nWHERE user_team.type = :type_1 AND user_team.user_id = :user_id_1'
[(0L,)]
>>> obj = UserCompanyLink
>>> q2 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q2) ; q2.all()
'SELECT count(user_company.type) AS cnt \nFROM user_company \nWHERE user_company.type = :type_1 AND user_company.user_id = :user_id_1'
[(0L,)]
>>> 
>>> my_union = q1.union_all(q2)
>>> query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'BaseQuery' object has no attribute 'c'

Is there a way to fix this?

In summary what I'm attempting to do is select counts from both tables, then union into another table and then add them.

Thank you.

You need to use my_union as subquery

my_union = q1.union_all(q2).subquery()
query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)

Here's my own problem solved, I used a slightly different approach than @rmn's however I think both should work:

    q_union = q1.union_all(q2)
    q_union_cnt = db.session.query(func.sum(q_union.subquery().columns.cnt).label("total_cnt"))
    admin_points = q_union_cnt.scalar()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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