一个标签列具有类似于“苹果 香蕉 橘子”和“草莓 香蕉 柠檬”的值。我希望找到与以下语句等效的SQLAlchemy语句:
SELECT * FROM table WHERE tags LIKE "%banana%";
我应该向 Class.query.filter()
传递什么来实现这个目的?
一个标签列具有类似于“苹果 香蕉 橘子”和“草莓 香蕉 柠檬”的值。我希望找到与以下语句等效的SQLAlchemy语句:
SELECT * FROM table WHERE tags LIKE "%banana%";
我应该向 Class.query.filter()
传递什么来实现这个目的?
每个列都有like()
方法,可以在query.filter()
中使用。给定搜索字符串,在两侧添加%
字符以在两个方向上搜索子字符串。
tag = request.form["tag"]
search = "%{}%".format(tag)
posts = Post.query.filter(Post.tags.like(search)).all()
在上面的答案基础上,如果有人在寻找解决方案,你也可以尝试使用'match'操作符代替'like'。不想有偏见,但它在Postgresql中完美地为我工作。
添加到上面的答案,谁寻找解决方案,您可以尝试使用“match”操作符而不是“like”。不想有偏见,但它在Postgresql中对我完美地起作用。
Note.query.filter(Note.message.match("%somestr%")).all()
它继承了像CONTAINS和MATCH这样的数据库函数。然而,在SQLite中不可用。
有关详细信息,请访问常见过滤器运算符
to_tsquery
来添加文本操作符,例如 OR
和 AND
https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES - Nickmatch
不支持部分字符串匹配(例如,abc%
匹配abcd
),而like
则支持。 - Nick如果您需要不区分大小写的模糊匹配实现:
session.query(TableName).filter(TableName.colName.ilike(f'%{search_text}%')).all()
试一下这段代码:
output = dbsession.query(<model_class>).filter(
<model_class>.email.ilike("%" + <email> + "%")
)
q = session.query(User).filter(User.name.like('e%'))
虽然接受的答案运行良好,但“ORM查询对象作为SQLAlchemy 2.0的遗留结构”(参考:Legacy Query API - SQLAlchemy 2.0文档)。
在Python 3.10代码片段中,与SQL LIKE
语句对应的SQLAlchemy v2.0等价于使用select
构造的方式如下所示:
from typing import List
from sqlalchemy import select
from sqlalchemy.orm import Session
...
def get_multi_like_tag_substring_bidirectional(
db: Session,
*,
tags_search_substring: str,
skip: int = 0,
limit: int = 10,
) -> List[Post]:
return db.scalars(
select(Post)
.where(Post.tags.like(f"%{tags_search_substring}%"))
.offset(skip)
.limit(limit)
).all()
...
banana_tagged_posts = get_multi_like_tag_substring_bidirectional(
db=db_session,
tags_search_substring = "banana"
)
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()
LIKE '%' :bar_tags '%'
语法吗?这很奇怪。 - Cédric ZUGERtags
列中添加前导和尾随空格,以便可以匹配所需的标签,确保只匹配完整的单词,防止'pineapple'匹配到 'apple' 或 'sqlachemy'匹配到 'sql'。tag = 'banana'
search = f"% {tag} %" # !spaces around the tag
query = select(MyTable).filter((' ' + MyTable.tags + ' ').like(search))
select(User).where(User.name.like(f'%{some_term}%'))
LIKE
子句的方法。
select(User.name).where(User.name.startswith('A'))
SELECT users.name
FROM users
WHERE (users.name LIKE :name_1 || '%')
select(User.name).where(User.name.endswith('e'))
SELECT users.name
FROM users
WHERE (users.name LIKE '%' || :name_1)
select(User.name).where(User.name.contains('i'))
SELECT users.name
FROM users
WHERE (users.name LIKE '%' || :name_1 || '%')
session.query
语法一起使用。使用PostgreSQL的like
(请参考上面接受的答案)在我这里不起作用,尽管情况匹配,但是ilike
(大小写不敏感的like
)可以。
tags
表,其中存储标签名称和其他标签信息,还将拥有一个task_tags
表,每个添加到任务中的标签都将有一条记录。因此,具有2个标签的任务将在task_tags
表中仅有2条记录。 - Daniel Kluev