sqlalchemyは複数の列をフィルタリングします


82

2つの列を組み合わせてフィルターを適用するにはどうすればよいですか?たとえば、「名」列と「姓」列の両方を同時に検索したいとします。1つの列のみを検索する場合の方法は次のとおりです。

query = meta.Session.query(User).filter(User.firstname.like(searchVar))

4
この質問は私が抱えている問題と一致すると思いましたが、答えは私の特定のシナリオには当てはまりません。名が「joe」で姓が「smith」の場合、提供されたsearchVarが「joesmith」の場合に一致するフィルターステートメントを探しています。つまり、テストを行う前に、フィールドを連結する(スペースを追加する)必要があります。非常に現実的なシナリオのようです。
Groovee60 2015年

1
@ Groovee60これはまさに私が探しているものです。ソリューションを見つけたら、共有していただければ幸いです。
Lilylakshi 2017年

回答:


84

それを行うにはいくつかの方法があります。

filter()および演算子)の使用

query = meta.Session.query(User).filter(
    User.firstname.like(search_var1),
    User.lastname.like(search_var2)
    )

filter_by()および演算子)の使用

query = meta.Session.query(User).filter_by(
    firstname.like(search_var1),
    lastname.like(search_var2)
    )

論理積filter()またはfilter_by()および演算子)

query = meta.Session.query(User).\
    filter_by(firstname.like(search_var1)).\
    filter_by(lastname.like(search_var2))

使用してor_()and_()と、not()

from sqlalchemy import and_, or_, not_

query = meta.Session.query(User).filter(
    and_(
        User.firstname.like(search_var1),
        User.lastname.like(search_var2)
    )
)

2
これらの異なるアプローチで注目すべきパフォーマンスの違いはありますか?
miek 2018年

2
さまざまなアプローチのほとんどが同じクエリを生成することになるため、ほとんどの場合、パフォーマンスの違いは見られません。
Asa Stallard 2018

私は少し混乱しています。filter_byドキュメントは言う:それはキーワード引数によってフィルタリングするためだというquery(Foo).filter_by(bar='baz')。これは、上記の回答で使用した構文とどのように関連していますか?
TEL

76

あなたは単にfilter複数回呼び出すことができます:

query = meta.Session.query(User).filter(User.firstname.like(searchVar1)). \
                                 filter(User.lastname.like(searchVar2))

36
大規模なmysqlテーブルで、複数のfilter()メソッドを使用することと、単一ので複数の条件の組み合わせ(byor_またはand_)を使用することの間にパフォーマンスの違いはありますfilterか?
exAres 2014

6
複数のfilter呼び出しは、論理的ANDではなく論理的に機能しORますか?
danodonovan 2015年

6
私はそうは思いません-str(User.filter(cond1).filter(cond2))を見ると、条件「and」だけで最終的なSQLが生成されます。
Shankar ARUL 2015年

60

SQLAlchemyのor_関数を使用して、複数の列を検索できます(Python自体と区別するためにアンダースコアが必要ですor)。

次に例を示します。

from sqlalchemy import or_
query = meta.Session.query(User).filter(or_(User.firstname.like(searchVar),
                                            User.lastname.like(searchVar)))

7
このよう|or_、の代わりに演算子を使用できますが、優先順位に(User.firstname.like(searchVar)) | (User.lastname.like(searchVar))注意する必要があります。|括弧を付けないと、比較演算子と混合すると非常に予期しない結果が生じる可能性があります。
ダニエルクルエフ2010

1
そうではないfilter.or_( case1, case 2)ですか?
fedorqui'SOは害をやめる '2013

2
質問はORMに関するものですが、リンクは式につながるため、これは間違っています。
user2846569 2015

1
私は複数のフィルターステートメントを使用していましたが、その前はレイテンシーが劇的に増加しました。私はそれをor_に変更しました、そしてそれははるかに速く戻ります。ありがとう@ gclj5
ジミー

2

複数の列で機能する一般的なコード。これは、アプリケーションに検索機能を条件付きで実装する必要がある場合にも使用できます。

search_key = "abc"
search_args = [col.ilike('%%%s%%' % search_key) for col in ['col1', 'col2', 'col3']]
query = Query(table).filter(or_(*search_args))
session.execute(query).fetchall()

注:%%クエリのフォーマットをスキップすることが重要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.