簡體   English   中英

如何使用SqlAlchemy通過聯接構造計數聚合?

[英]How can I construct a count aggregation over a join with SqlAlchemy?

我有一個用戶表,一個這些用戶可能屬於的組表以及一個用戶與組之間的聯接表。

這在SQLAlchemy中表示如下:

class User(Base):
    __tablename__ = 'user'
    user_id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
    email = Column(String(250), nullable=False)
    groups = relationship('Group', secondary='user_group_pair')

class Group(Base):
    __tablename__ = 'group'
    group_id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
    date_created = Column(String(250), nullable=False)
    members = relationship('User', secondary='user_group_pair')

class User_Group_Pair(Base):
    __tablename__ = 'user_group_pair'
    user_group_pair_id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.user_id'))
    group_id = Column(Integer, ForeignKey('group.group_id'))
    user = relationship(User, backref=backref("group_assoc"))
    group = relationship(Group, backref=backref("user_assoc"))

我正在嘗試解決以下簡單問題:

我想編寫一個查詢,該查詢將返回用戶列表以及每個用戶所屬的組的數量。

這需要來自User和User_Group_Pair的數據(因此,我的問題的標題為何指向聯接),以及由user_id分組的計數匯總。

我不確定為什么這行不通:

subq = session.query(User_Group_Pair.user_id.label('user_id'), func.count(User_Group_Pair.user_group_pair_id).label('count')).\
group_by(User_Group_Pair.user_id).order_by('count ASC').subquery()

result = session.query(User).join(subq, User.user_id == subq.user_id).all()

我收到此錯誤:

'Alias' object has no attribute 'user_id'

但是,請注意,我已經將User_Group_Pair.user_id標記為“ user_id” ...有什么想法嗎?

謝謝

http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#using-subqueries

Query上的subquery()方法產生一個SQL表達式構造,該構造表示嵌入在別名中的SELECT語句。 可以通過名為c的屬性訪問該語句上的列。

您可以在查詢中使用帶有.c.column_name列名

result = session.query(User).join(subq, User.user_id == subq.c.user_id).all()

只需將subq.user_id更改為subq.c.user_idc代表columns )即可使其工作:

result = session.query(User).join(subq, User.user_id == subq.c.user_id).all()

但是,您仍然只會獲得至少屬於一個組的那些用戶,並且查詢結果中不會真正返回組的數量。 以下查詢是解決此問題的一種方法:

q = (session.query(User, func.count(Group.group_id).label("num_groups"))
     .outerjoin(Group, User.groups)
     .group_by(User.user_id)
     )
for b, num_groups in q:
    print(b, num_groups)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM