2013-10-20 6 views
6

Diciamo che ho classi SQL Alchemy ORM:interrogazione SQLAlchemy per oggetto con conteggio del rapporto

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')) 

E voglio interrogare per essenzialmente i seguenti:

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

Tuttavia, questo è chiaramente 1 + n query, che è terribile. Qual è il modo corretto per farlo, con 1 query? In SQL normale, vorrei farlo con qualcosa sulla falsariga di:

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

hai guardato il tutorial ORM, in particolare, la sezione denominata [Interrogazione con Unisce] (http://docs.sqlalchemy.org/en/rel_0_8/orm/tutorial.html#querying-with-joins)? –

+2

Sì, l'ho guardato, tuttavia non mi è chiaro come fare il join seguito dal gruppo e aggiungere un conteggio alla lista finale di colonne. – WirthLuce

risposta

7

costruire una subquery che i gruppi e conta ID di sessione da piste, e si uniscono a quella nella query finale.

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

Non c'è un modo migliore per farlo? Sembra molto prolisso. In SQL regolare sarebbe abbastanza semplice. – WirthLuce

+1

@WirthLuce: non riesco a vedere come questa risposta sia più dettagliata del codice 'SQL'. – van

Problemi correlati