SQLAlchemyでリレーションに自動フィルターを追加する方法は?
-
06-07-2019 - |
質問
SQLAlchemy 0.5rcを使用していますが、リレーションに自動フィルターを追加して、そのリレーションのレコードを取得しようとするたびに、「リモート」を無視するようにします。 「論理的に削除済み」としてフラグが付けられている場合(子テーブルのブールフィールド)
たとえば、オブジェクト" parent"が「子供」がいる持っている関係
3つのレコードがありますが、「親」を照会すると、そのうちの1つが論理的に削除されます。 SQLAが欲しい
2つの子のみを持つ親オブジェクトを取得します。
どうすればいいですか? 「および」を追加することにより、 primaryjoinの条件
関係のパラメーター? (例:" Children.parent_id == Parent.id and Children.logically_deleted == False
"ですが、このように" and"を書くのは正しいですか?)
編集:
この方法でなんとかできました
children = relation("Children", primaryjoin=and_(id == Children.parent_id, Children.logically_deleted==False))
しかし、代わりにprimaryjoinとして文字列を使用する方法はありますか?
解決
and_()関数は、&と一緒にSQLAlchemyで論理結合を行う正しい方法です。演算子ですが、驚くべき優先順位の規則、つまり比較演算子よりも高い優先順位があるため、後者には注意してください。
文字列をtext()コンストラクターとの主な結合として使用することもできますが、これにより、eagerloadingと結合に伴うテーブルエイリアシングでコードが破損します。
論理削除の場合、削除された値を無視する選択よりもクラス全体をマップする方がよい場合があります。
mapper(Something, select([sometable], sometable.c.deleted == False))
他のヒント
しかし、代わりにprimaryjoinとして文字列を使用する方法はありますか?
次を使用できます。
children = relationship("Children", primaryjoin="and_(Parent.id==Children.parent_id, Children.logically_deleted==False)"
これは私のために働いた!
現在は0.4.somethingのみを開発していますが、次のように提案します。
db.query(Object).filter(Object.first==value).filter(Object.second==False).all()
それがあなたがやろうとしていることだと思いますか?
(注:実際のコードではなく、Webブラウザーで記述されています!)