SQLAlchemyのfilterとfilter_byの違い


304

SQLAlchemy filterとのfilter_by機能の違いを誰かが説明できますか?どちらを使用すればよいですか?

回答:


393

filter_by 次のように、通常のkwargsを使用した列名の簡単なクエリに使用されます

db.users.filter_by(name='Joe')

filterkwargsを使用せずに、db.users.nameオブジェクトにオーバーロードされている '=='等号演算子を使用して、同じことを実行できます。

db.users.filter(db.users.name=='Joe')

次のfilterような式など、を使用してより強力なクエリを作成することもできます。

db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))


22
これは内部でどのように機能しますか?思いませんdb.users.name=='Ryan'定数に一度評価し、その後に続いから意味が?これを機能させるにはラムダを使用する必要があるようです。
Hamish Grubijan 2013

46
等値演算子が過負荷
Daniel Velkov 2013

9
type(model.column_name == 'asdf')sqlalchemy.sql.elements.BinaryExpression
Nick T

11
使用時には注意してください.filter。以下のようなクエリではid=12345query(users).filter(id == id)フィルターを適用しませんusers.id。代わりに、id == idとして評価しTrue、すべてのユーザーを返します。.filter(users.id == id)(上記でデモしたように)使用する必要があります。私は今日早くこの間違いをしました。
Nico Cernek、

118

実際には、これらを元々マージしていました。つまり、SQL式またはキーワード引数(またはその両方)を渡すことができる*argsand を受け入れる「フィルター」のようなメソッドがありました**kwargs。実際にははるかに便利だと思いますが、column == expressionとの違いはまだ解消されていないため、人々は常に混乱していましたkeyword = expression。したがって、それらを分割します。


30
私は約あなたのポイントだと思いcolumn == expression対のkeyword = expression間の違いについて作るために重要なポイントであるfilterfilter_by。ありがとう!
Hollister

2
私はsqlalchemyを初めて使用するので、これが愚かな質問である場合は失礼しますが、filter_by()は「price> = 100」などの非常に単純な条件でさえも許可しないようです。それで、 "price = 100"のような非常に単純な条件でのみ使用できるのに、なぜfilter_by()関数があるのでしょうか。
PawelRoman、2014年

18
人々はそれを好むから
zzzeek 2014年

3
それらの間にパフォーマンスの違いはありますか?それfilter_byより少し速いかもしれないと思っていましたfilter
Devi

6
使用のポイントはfilter_by、そのクラスのフィールド名を記述できることです。flter実際の列オブジェクトが必要ですが、通常、少なくとも冗長なクラス名を入力(および読み取る)する必要があります。したがって、等式でフィルタリングする場合は、かなり便利です。
jsbueno 2016年

36

filter_byキーワード引数を使用しますが、次のfilterようなPythonicフィルタリング引数を許可しますfilter(User.name=="john")


34

これは、クエリの書き込みを高速化するための構文シュガーです。擬似コードでのその実装:

def filter_by(self, **kwargs):
    return self.filter(sql.and_(**kwargs))

ANDの場合、次のように簡単に記述できます。

session.query(db.users).filter_by(name='Joe', surname='Dodson')

ところで

session.query(db.users).filter(or_(db.users.name=='Ryan', db.users.country=='England'))

次のように書くことができます

session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))

また、getメソッドを介してPKでオブジェクトを直接取得することもできます。

Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)

getケースを使用する場合、identity mapキャッシュとして使用できるデータベースリクエストなしでオブジェクトを返すことができることが重要です(トランザクションに関連付けられています)。


これらのコード例は誤解を招くものです。宣言的なベーステーブルのクラスとインスタンスには、フィルターもクエリメソッドもありません。彼らはセッションを使用します。
カメはかわいい

users.filter前回の回答から再現します。そして、その私のせいかもしれ:) query属性がありQUERY_PROPERTYと、最近そのかなりの標準的な砂糖
enomad
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.