web-dev-qa-db-ja.com

SQLAlchemyのfilterとfilter_byの違いは何ですか?

SQLAlchemyのfilter関数とfilter_by関数の違いを説明できる人はいますか?私は混乱しており、実際に違いを見ることができません。どちらを使用すべきですか?

252
bodacydo

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

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

同じことは、filterでも実現できます。kwargsを使用せず、代わりにdb.users.nameオブジェクトでオーバーロードされた「==」等号演算子を使用します。

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

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

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

316
Daniel Velkov

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

107
zzzeek

filter_byはキーワード引数を使用しますが、filterfilter(User.name=="john")のようなPythonフィルタリング引数を使用できます

33
Johannes Charra

クエリの記述を高速化するための構文シュガーです。擬似コードでの実装:

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からのデータベース要求なしにオブジェクトを返すことができることが重要です(トランザクションに関連付けられています)

28
enomad