2017-09-26 47 views
0

我有兩個表:篩選父母尊重一些指標分析

class Parent(Base): 
    __tablename__ = 'parents' 
    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) 
    min_quantity = sqlalchemy.Column(sqlalchemy.Integer, default=0, nullable=False) 
    children = sqlalchemy.orm.relationship('Child', backref=sqlalchemy.orm.backref('parent') 

class Child(Base): 
    __tablename__ = 'children' 
    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) 
    expiration_date = sqlalchemy.Column(sqlalchemy.Date) 
    parent_id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey('parents.id')) 

什麼是選擇具有至少MIN_QUANTITY兒童與到期日期< datetime.today只有父對象最簡單的方法() ?

我可以查詢每一位家長的對象,然後做一個列表理解:

parents = session.query(Parent).all() 
ok_parents = [parent for parent in parents if len([child for child in parent.children if child.expiration_date < datetime.today()]) > parent.min_quantity] 

但感覺並不像真正高效的代碼。我想我只能在一個查詢中做到這一點,並且我懷疑我的查詢中必須使用having(),但是由於我對sqlachemy的知識(以及一般的SQL)仍然有限,我沒有設法解決這個問題。

所以基本上,我願意接受任何提議。

回答

0

你是對的,你可以使用HAVING子句。另外例如,您可以詢問家長帶着孩子參加,由家長ID過濾那些到期日期,組,並在關係由每組的行數過濾組到最小數量:

ok_parents = session.query(Parent).\ 
    join(Child).\ 
    filter(Child.expiration_date < datetime.today()).\ 
    group_by(Parent.id).\ 
    having(func.count(1) > Parent.min_quantity).\ 
    all() 

在一個警告上面的查詢是,由於內部聯接,沒有孩子的父母不能成爲結果。要解決此問題,您將使用outerjoin(Child)並通過或者沒有子項(Child.id.is_(None))或過期日期來篩選結果行。