SQLAlchemy 相当于 SQL“LIKE”语句
- 2025-04-16 08:56:00
- admin 原创
- 24
问题描述:
标签列的值包括“苹果香蕉橙子”和“草莓香蕉柠檬”。我想找到 SQLAlchemy 中与以下语句等效的语句:
SELECT * FROM table WHERE tags LIKE "%banana%";
我应该传递什么Class.query.filter()
来做到这一点?
解决方案 1:
每列都有like()
一个方法,可以在中使用query.filter()
。给定一个搜索字符串,%
在两侧添加一个字符,即可在两个方向上作为子字符串进行搜索。
tag = request.form["tag"]
search = "%{}%".format(tag)
posts = Post.query.filter(Post.tags.like(search)).all()
解决方案 2:
如果您想要不区分大小写的 like 子句实现:
session.query(TableName).filter(TableName.colName.ilike(f'%{search_text}%')).all()
解决方案 3:
除了上面的答案之外,如果有人想寻找解决方案,也可以尝试使用“match”运算符代替“like”。我无意偏袒任何人,但它在 Postgresql 中对我来说非常有效。
Note.query.filter(Note.message.match("%somestr%")).all()
它继承了数据库函数,例如CONTAINS和MATCH。但是,它在 SQLite 中不可用。
更多信息请见常见过滤运算符
解决方案 4:
试试这个代码:
output = dbsession.query(<model_class>).filter(
<model_class>.email.ilike("%" + <email> + "%")
)
解决方案 5:
除了显而易见的
select(User).where(User.name.like(f'%{some_term}%'))
SQLAlchemy 提供了一些其他生成LIKE
子句的方法。
startswith:搜索词后跟 % 通配符
select(User.name).where(User.name.startswith('A'))
SELECT users.name
FROM users
WHERE (users.name LIKE :name_1 || '%')
endswith:搜索词前面带有 % 通配符
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 || '%')
与like和ilike方法类似,这些方法都有一个不区分大小写的对应项:istartswith、iendswith和icontains。
所有这些方法也可用于核心表列,并且也可以与旧session.query
语法一起使用。
解决方案 6:
在 SQLAlchemy 1.4/2.0 中:
q = session.query(User).filter(User.name.like('e%'))
解决方案 7:
如果您使用本机 SQL,您可以参考我的代码,否则请忽略我的答案。
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()
解决方案 8:
虽然接受的答案工作正常,但“ ORM 查询对象是 SQLAlchemy 2.0 的遗留构造”(参考:遗留查询 API - SQLAlchemy 2.0 文档)。
LIKE
与使用该构造的SQL 语句对应的 SQLAlchemy v2.0 等效项select
如下面的 python 3.10 代码片段所示:
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"
)
解决方案 9:
这些年来我一直在使用的东西:
model = MyModel
col = "name_of_my_column"
value = "your-value"
query = model.query.filter(getattr(model, col).like("%{}%".format(value))).all()
解决方案 10:
使用 PostgreSQL like
(参见上面接受的答案)虽然大小写匹配,但对我来说不起作用,但是ilike
(不区分大小写)却起作用。
解决方案 11:
正如您在下面看到的,我在tags
列中添加了前导空格和尾随空格,以便我可以匹配由空格包围的所需标签,以确保仅匹配完整的单词,防止“pineapple”匹配“apple”或“sqlachemy”匹配“sql”:
tag = 'banana'
search = f"% {tag} %" # !spaces around the tag
query = select(MyTable).filter((' ' + MyTable.tags + ' ').like(search))
解决方案 12:
这样做对我(Oracle)来说就像本机 SQL
"SELECT * FROM table WHERE tags LIKE '%' || :bar_tags || '%' "
扫码咨询,免费领取项目管理大礼包!