2011-10-17 12 views
7

私はDocumentPersonという2つのモデルがあるとします。 Documentは「所有者」プロパティを介してPersonとの関係を持っています。今:SqlAlchemyでjoinloadedテーブルをフィルタリングする方法は?

session.query(Document)\ 
    .options(joinedload('owner'))\ 
    .filter(Person.is_deleted!=True) 

ダブル参加表Person。 1人の人物のテーブルが選択され、倍増したものがフィルタリングされます。これは、ドキュメント行がフィルタリングされないようにしたいのです。

joinloadedテーブル/モデルにフィルタを適用するにはどうすればよいですか?

答えて

14

あなたは正しいです、テーブルPersonは、得られSQLに2回使用されますが、それらのそれぞれが異なる目的を果たす:

  • 1は、条件をフィルタリングすることである:filter(Person.is_deleted != True)
  • 他は熱心にあります関係をロードしてください:options(joinedload('owner'))

しかし、クエリの結果が正しくないのは、フィルタ条件が完全でないためです。それが正しい結果を生成させるために、あなたは、2つのモデルに参加する必要があります。

qry = (session.query(Document). 
     join(Document.owner). # THIS IS IMPORTANT 
     options(joinedload(Document.owner)). 
     filter(Person.is_deleted != True) 
     ) 

これは、それはまだPersonテーブルに2つの参照を(JOINを)持っているだろうにもかかわらず、正しい行を返します。クエリの実際の解決策は、joinedloadの代わりにcontains_eagerを使用することです。

qry = (session.query(Document). 
     join(Document.owner). # THIS IS STILL IMPORTANT 
     options(contains_eager(Document.owner)). 
     filter(Person.is_deleted != True) 
     ) 
関連する問題