Sto avendo difficoltà a ottimizzare le mie query SQLAlchemy. La mia conoscenza di SQL è molto semplice, e non riesco a ottenere le cose che mi servono dai documenti SQLAlchemy.SQLAlchemy: più conteggi in una query
Supponiamo la seguente relazione molto di base uno-a-molti:
class Parent(Base):
__tablename__ = "parents"
id = Column(Integer, primary_key = True)
children = relationship("Child", backref = "parent")
class Child(Base):
__tablename__ = "children"
id = Column(Integer, primary_key = True)
parent_id = Column(Integer, ForeignKey("parents.id"))
naughty = Column(Boolean)
come potevo:
- tuple query di
(Parent, count_of_naughty_children, count_of_all_children)
per ciascun genitore?
Dopo tempo decente trascorso googling, ho trovato come interrogare quei valori separatamente:
# The following returns tuples of (Parent, count_of_all_children):
session.query(Parent, func.count(Child.id)).outerjoin(Child, Parent.children).\
group_by(Parent.id)
# The following returns tuples of (Parent, count_of_naughty_children):
al = aliased(Children, session.query(Children).filter_by(naughty = True).\
subquery())
session.query(Parent, func.count(al.id)).outerjoin(al, Parent.children).\
group_by(Parent.id)
ho cercato di combinarli in modi diversi, ma non sono riuscito a ottenere ciò che voglio.
- Interroga tutti i genitori che hanno oltre l'80% di bambini birichini? Modifica: cattivo potrebbe essere NULL.
Immagino che questa query sarà basata sul precedente, filtrando per cattivo/tutto rapporto.
Qualsiasi aiuto è apprezzato.
EDIT: Grazie all'aiuto di Antti Haapala, ho trovato la soluzione alla seconda domanda:
avg = func.avg(func.coalesce(Child.naughty, 0)) # coalesce() treats NULLs as 0
# avg = func.avg(Child.naughty) - if you want to ignore NULLs
session.query(Parent).join(Child, Parent.children).group_by(Parent).\
having(avg > 0.8)
Essa trova media se di naughty
variabile, trattando False e NULL come 0, e Vero bambini 1. Testato con back-end MySQL, ma dovrebbe funzionare anche su altri.
Grazie, funziona perfettamente! – meandrobo