sqlalchemy 여러 열 필터링


82

두 개의 열을 결합하고 필터를 적용하려면 어떻게합니까? 예를 들어 "이름"과 "성"열을 동시에 검색하려고합니다. 하나의 열만 검색하는 경우 다음과 같이합니다.

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

4
이 질문이 내가 가진 문제와 일치한다고 생각했지만 답변이 내 특정 시나리오에 적용되지 않습니다. 이름이 "joe"이고 성이 "smith"이면 제공된 searchVar가 "joe smith"일 때 일치하는 필터 문을 찾고 있습니다. 즉, 테스트를 수행하기 전에 필드를 연결 (공백 추가)해야합니다. 매우 실제 시나리오처럼 보입니다.
Groovee60

1
@ Groovee60 이것이 바로 제가 찾고있는 것입니다. 해결책을 찾았다면 공유해 주시면 감사하겠습니다.
Lilylakshi

답변:


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 2011 년

2
대부분의 다른 접근 방식은 동일한 쿼리를 생성하므로 대부분의 경우 성능 차이가 나타나지 않습니다.
Asa Stallard

조금 혼란 스러워요. 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
여러 filter()메서드를 사용하는 것과 대규모 mysql 테이블에서 단일에서 여러 조건의 조합 (by or_또는 and_)을 사용하는 것 사이에 성능 차이가 filter있습니까?
exAres 2014-07-28

6
여러 filter호출이 논리가 AND아닌 논리처럼 작동 OR합니까?
danodonovan 2015 년

6
나는 그렇게 생각하지 않을 것이다-당신이 str (User.filter (cond1) .filter (cond2))를 보면 조건이 "and"ed 인 최종 SQL이 생성된다.
Shankar ARUL 2015

60

SQLAlchemy의 or_함수 를 사용 하여 둘 이상의 열에서 검색 할 수 있습니다 (파이썬의 열과 구별하기 위해 밑줄이 필요합니다 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)), 그러나 |우선 순위에 주의해야합니다. 괄호가 없으면 비교 연산자와 혼합 될 때 예상치 못한 결과가 매우 발생할 수 있습니다.
Daniel Kluev 2010 년

1
filter.or_( case1, case 2)그래?
fedorqui 'SO stop harming'May

2
질문은 ORM에 관한 것이지만 링크는 표현으로 이어지기 때문에 이것은 잘못되었습니다.
user2846569

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.