2014-01-14 3 views
5

Personは、Buildingを有する。SQLAlchemyでコレクションのサイズが0か空であるかどうかを確認するクエリ?

Personは、私が彼らのgroupsコレクション内の任意のGroupを持っていない特定のbuildingからpeopleのすべてを返すようにしたいGroup

多く持っています。
おそらく長さが0のグループリストを持っている人で検索できますか? のような何か:

unassigned=Person.query.filter(Person.building==g.current_building,Person.groups.any()).all() 

答えて

11

使用否定(~anyと:

q = session.query(Person) 
q = q.filter(Person.building == g.current_building) 
q = q.filter(~Person.groups.any()) 

anyはあなたのケースで必要以上に強力ですが、それはうまく仕事を行います。

+1

この機能は「高価」なのですか? – Johnston

+1

私はそれが高価になるとは考えていませんが、よくあることですが、それは依存します。データ密度、データベースインデックス、RDBMS自体によって、他のソリューションより速くて遅くなる場合があります。 'any'はサブクエリを生成しますが、SQLの「良い」部分ではありませんが、ここではSAがユーザから隠しているものです。 – van

+0

5Gbのsqliteデータベースの私の同様のケースでは、外部結合を使うのが100倍以上高速です( 'any()'バージョンが終了するのを待たずに) 'any()'としています: 'session.query( Ebook.id).outerjoin(Sentence).filter(Sentence.id == None) ' – Eponymous

0

最初に建物あたりのグループを数え、その数をフィルタします。

gc = session.query(
    Person.id, 
    db.func.count(Group.id).label('gc') 
).join(Person.groups).group_by(Person.id).subquery() 

unassigned = session.query(Person).join(
    (gc, gc.c.person_id == Person.id) 
).filter(
    Person.building == g.current_building, 
    gc.c.gc == 0 
).all() 
関連する問題