SQLAlchemyのfilter
関数とfilter_by
関数の違いを説明できる人はいますか?私は混乱しており、実際に違いを見ることができません。どちらを使用すべきですか?
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'))
これらは元々マージされていました。つまり、* argsと** kwargsを受け入れる「フィルター」のようなメソッドがあり、SQL式またはキーワード引数(またはその両方)を渡すことができました。私は実際にそれがはるかに便利だと感じていますが、人々はいつもcolumn == expression
とkeyword = expression
の違いをまだ乗り越えているので、いつも混乱しています。そこで、それらを分割します。
filter_by
はキーワード引数を使用しますが、filter
はfilter(User.name=="john")
のようなPythonフィルタリング引数を使用できます
クエリの記述を高速化するための構文シュガーです。擬似コードでの実装:
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
からのデータベース要求なしにオブジェクトを返すことができることが重要です(トランザクションに関連付けられています)