sqlalchemy lọc nhiều cột


81

Làm cách nào để kết hợp hai cột và áp dụng bộ lọc? Ví dụ: tôi muốn tìm kiếm trong cả hai cột "họ" và "họ" cùng một lúc. Đây là cách tôi đã thực hiện nếu chỉ tìm kiếm một cột:

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

4
Tôi nghĩ rằng câu hỏi này phù hợp với vấn đề mà tôi gặp phải, nhưng câu trả lời không áp dụng cho trường hợp cụ thể của tôi. Nếu tên đầu tiên là "joe" và họ là "smith", tôi đang tìm một câu lệnh bộ lọc sẽ khớp khi searchVar được cung cấp là "joe smith". Tức là, các trường cần phải được nối (có thêm khoảng trắng) trước khi thực hiện kiểm tra. Có vẻ như một kịch bản rất thực tế.
Groovee60

1
@ Groovee60 Đây chính xác là những gì tôi đang tìm kiếm. Tôi sẽ đánh giá cao nếu bạn có thể chia sẻ giải pháp của mình, nếu bạn tìm thấy.
Lilylakshi

Câu trả lời:


82

Có một số cách để làm điều đó:

Sử dụng filter()( toán tử)

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

Sử dụng filter_by()( toán tử)

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

Chuỗi filter()hoặc filter_by()( nhà điều hành)

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

Sử dụng 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
Có bất kỳ sự khác biệt đáng chú ý nào về hiệu suất cho những cách tiếp cận khác nhau này không?
Miek

2
Hầu hết các cách tiếp cận khác nhau sẽ tạo ra cùng một truy vấn, vì vậy trong hầu hết các trường hợp, bạn sẽ không thấy sự khác biệt về hiệu suất.
Asa Stallard

Tôi hơi bối rối. Các filter_bytài liệu nói rằng đó là để lọc bởi tham số keyword: query(Foo).filter_by(bar='baz'). Điều đó liên quan như thế nào đến cú pháp bạn đã sử dụng trong câu trả lời ở trên?
tel

76

Bạn chỉ cần gọi filternhiều lần:

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

36
có sự khác biệt nào về hiệu suất giữa việc sử dụng nhiều filter()phương pháp và sử dụng kết hợp nhiều điều kiện (bằng or_hoặc and_) trong một filterbảng mysql lớn không?
exAres

6
Nhiều filtercuộc gọi sẽ hoạt động giống như một logic ANDhơn là một OR?
danodonovan

12
nó sẽ là VÀ
Lyman Zerga

6
Tôi sẽ không nghĩ như vậy - khi bạn nhìn vào str (User.filter (cond1) .filter (cond2)) tạo ra sql cuối cùng chỉ với các điều kiện "và" ed.
Shankar ARUL - jupyterdata.com

60

Bạn có thể sử dụng or_hàm của SQLAlchemy để tìm kiếm trong nhiều cột (cần có dấu gạch dưới để phân biệt với hàm của Python or).

Đây là một ví dụ:

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

7
Bạn có thể sử dụng |toán tử thay vì or_, như thế này - (User.firstname.like(searchVar)) | (User.lastname.like(searchVar)), tuy nhiên bạn nên cẩn thận với mức độ |ưu tiên, không có dấu ngoặc đơn, nó có thể tạo ra kết quả RẤT bất ngờ khi trộn với các toán tử so sánh.
Daniel Kluev

1
Có nên không filter.or_( case1, case 2)?
fedorqui 'VẬY đừng làm hại nữa'

2
Điều này là sai, vì câu hỏi là về ORM nhưng liên kết dẫn đến các biểu thức.
user2846569 19/02/15

1
Tôi đã sử dụng nhiều câu lệnh bộ lọc trước đó, điều này làm tăng độ trễ đáng kể. Tôi đã thay đổi nó thành or_ và nó trả về nhanh hơn NHIỀU. Cảm ơn bạn @ gclj5
Jimmy

2

Một đoạn mã chung sẽ hoạt động cho nhiều cột. Điều này cũng có thể được sử dụng nếu có nhu cầu triển khai có điều kiện chức năng tìm kiếm trong ứng dụng.

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()

Lưu ý: điều %%quan trọng là bỏ qua% định dạng truy vấn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.