2013-10-20 128 views
6

的計數對象可以說我有SQL鍊金術ORM類:SQLAlchemy的查詢與關係

class Session(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    user_agent = db.Column(db.Text, nullable=False) 

class Run(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 

    session_id = db.Column(db.Integer, db.ForeignKey('session.id')) 
    session = db.relationship('Session', backref=db.backref('runs', lazy='dynamic')) 

我想查詢主要是:

((session.id, session.user_agent, session.runs.count()) 
    for session in Session.query.order_by(Session.id.desc())) 

然而,這顯然是1 + n個查詢,這很糟糕。有1個查詢,這樣做的正確方法是什麼?在正常的SQL,我會沿着線的東西做到這一點:

SELECT session.id, session.user_agent, COUNT(row.id) FROM session 
LEFT JOIN rows on session.id = rows.session_id 
GROUP BY session.id ORDER BY session.id DESC 
+0

你有看了看ORM教程,具體而言,標記的部分(http://docs.sqlalchemy.org/en/rel_0_8/orm/tutorial.html#querying-with-joins [與加入查詢] )? –

+2

是的,我確實看過它,但是我不清楚如何在羣組之後進行連接,並在最終列表中添加一個計數。 – WirthLuce

回答

7

構造一個子查詢組和計算從運行會話ID,並加入到您的最終查詢。

sq = session.query(Run.session_id, func.count(Run.session_id).label('count')).group_by(Run.session_id).subquery() 
result = session.query(Session, sq.c.count).join(sq, sq.c.session_id == Session.id).all() 
+2

有沒有更好的方法來做到這一點?它看起來很冗長。在常規的SQL中,它會非常簡單。 – WirthLuce

+1

@WirthLuce:我看不出這個答案比你的SQL代碼更冗長。 – van