SQLAlchemy: несколько подсчетов в одном запросе

Я с трудом оптимизирую свои запросы SQLAlchemy. Мои знания SQL очень просты, и я просто не могу получить то, что мне нужно, из документации по SQLAlchemy.

Предположим следующее очень простое отношение один ко многим:

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)

Как я мог:

Запрос кортежей(Parent, count_of_naughty_children, count_of_all_children) для каждого родителя?

После приличного времени, проведенного в поиске, я нашел, как запросить эти значения отдельно:

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

Я пытался объединить их по-разному, но не смог получить то, что я хочу.

Опросите всех родителей, у которых более 80% непослушных детей? Редактировать: непослушный может быть NULL.

Я полагаю, что этот запрос будет основан на предыдущем запросе с фильтрацией по непослушному / всему отношению.

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ : Благодаря помощи Антти Хаапала я нашел решение второго вопроса:

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)

Он находит средний, если детскийnaughty переменная, рассматривая False и NULL как 0, а True как 1. Протестировано с бэкэндом MySQL, но должно работать и на других.

Ответы на вопрос(2)

Ваш ответ на вопрос