SQLAlchemy tương đương với câu lệnh SQL “LIKE”


85

Cột thẻ có các giá trị như "táo chuối cam" và "dâu tây chuối chanh". Tôi muốn tìm câu lệnh tương đương SQLAlchemy để

SELECT * FROM table WHERE tags LIKE "%banana%";

Tôi nên vượt qua Class.query.filter()những gì để làm điều này?

Câu trả lời:


172

Mỗi cột có like()phương thức, có thể được sử dụng trong query.filter(). Cho một chuỗi tìm kiếm, hãy thêm một %ký tự vào hai bên để tìm kiếm dưới dạng chuỗi con theo cả hai hướng.

tag = request.form["tag"]
search = "%{}%".format(tag)
posts = Post.query.filter(Post.tags.like(search)).all()

1
Hoàn hảo! Bạn có biết nếu có cách nào tốt hơn để phân biệt giữa táo và dứa hơn là thêm một khoảng trống ở đầu không?
Gary Oldfaber

3
Cách tốt nhất là chỉ cần chuẩn hóa cơ sở dữ liệu của bạn và thêm 2 bảng riêng biệt cho các thẻ và quan hệ từ khóa với nhiệm vụ, sau đó sử dụng JOIN thay vì LIKE. Nếu không, có, có vẻ như bạn sẽ phải có một số loại dấu phân tách xung quanh mỗi thẻ trong chuỗi. Khoảng trống hàng đầu là không đủ, vì còn có bút và bút chì, với% pen%. Nếu bạn làm điều gì đó như "| táo | dứa | bút | bút chì |" và khớp với "% | pen |%" nó không được va chạm.
Daniel Kluev

1
Với việc chuẩn hóa, tôi không chắc làm thế nào tôi sẽ có nhiều thẻ được liên kết với một nhiệm vụ nhất định hoặc ngược lại bằng cách sử dụng bản đồ thẻ. Giải pháp "Toxi" dường như để nhóm bộ sưu tập thẻ thành một mục duy nhất, thay vì lưu trữ từng thẻ riêng lẻ? Và phương pháp được sử dụng trong công thức này ( elixir.ematia.de/trac/wiki/Recipes/TagCloud ) dường như chỉ cho phép một thẻ cho mỗi mục. Những nguồn nào sẽ là tốt nhất để làm sáng tỏ chủ đề này? Tôi cũng đã đọc cái này ( dev.mysql.com/tech-resources/articles/… ), nhưng không thể hình dung cách quản lý nhiều thẻ.
Gary Oldfaber

2
Như tôi đã nói, bạn cần hai bảng. Về cơ bản, mối quan hệ Nhiều-Nhiều điển hình của nó, vì vậy bạn có thể làm theo hướng dẫn của SQLAlchemy về nó: sqlalchemy.org/docs/… Bạn sẽ có tagsbảng, nơi bạn lưu trữ tên thẻ và thông tin thẻ khác, và bạn sẽ có task_tagsbảng, sẽ có một bản ghi cho mỗi thẻ được thêm vào nhiệm vụ. Vì vậy, tác vụ với 2 thẻ sẽ chỉ có 2 bản ghi trong task_tagsbảng.
Daniel Kluev,

11

Thêm vào câu trả lời ở trên, bất kỳ ai đang tìm kiếm giải pháp, bạn cũng có thể thử toán tử 'khớp' thay vì 'thích'. Không muốn bị thiên vị nhưng nó hoàn toàn phù hợp với tôi trong Postgresql.

Note.query.filter(Note.message.match("%somestr%")).all()

Nó kế thừa các chức năng cơ sở dữ liệu như CONTAINSMATCH . Tuy nhiên, nó không có sẵn trong SQLite.

Để biết thêm thông tin, hãy truy cập Các toán tử bộ lọc phổ biến


8
Sự khác biệt giữa hai toán tử này là gì?
buhtz

@buhtz tùy thuộc vào phần phụ trợ DB của bạn, hãy xem tài liệu SQL-Alchemy: docs.sqlalchemy.org/en/14/core/… Trong Postgres, bạn nhận được to_tsquerynó cho phép bạn thêm toán tử văn bản cho những thứ như ORAND postgresql.org/docs/current/…
Nick

7

thử mã này

output = dbsession.query(<model_class>).filter(<model_calss>.email.ilike('%' + < email > + '%'))


0

Nếu bạn sử dụng sql gốc, bạn có thể tham khảo mã của tôi, nếu không thì chỉ cần bỏ qua câu trả lời của tôi.

SELECT * FROM table WHERE tags LIKE "%banana%";
from sqlalchemy import text

bar_tags = "banana"

# '%' attention to spaces
query_sql = """SELECT * FROM table WHERE tags LIKE '%' :bar_tags '%'"""

# db is sqlalchemy session object
tags_res_list = db.execute(text(query_sql), {"bar_tags": bar_tags}).fetchall()

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.