SQLAlchemy等效于SQL“ LIKE”语句


85

标签列具有“苹果香蕉橙”和“草莓香蕉柠檬”之类的值。我想找到等效的SQLAlchemy语句

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

我应该怎么Class.query.filter()做才能做到这一点?

Answers:


172

每列都有一个like()方法,可以在中使用query.filter()。给定一个搜索字符串,请%在任一侧添加一个字符以在两个方向上作为子字符串进行搜索。

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

1
完善!您知道是否有比添加领先空间更好的区分苹果和菠萝的方法?
Gary Oldfaber 2010年

3
最好的方法是仅规范化数据库,并为标记和标记与任务的关系添加2个单独的表,然后使用JOIN代替LIKE。否则,是的,似乎您将不得不在字符串中的每个标签周围使用某种分隔符。前导空间不足,因为还有笔和铅笔(含%pen%)。如果您执行“ |苹果|菠萝|笔|铅笔|”之类的操作 并匹配“%| pen |%”,则不应冲突。
丹尼尔·克鲁夫

1
通过规范化,我不太确定如何使用给定任务关联多个标签,反之亦然。“ Toxi”解决方案似乎将标签集合分组为单个项目,而不是单独存储每个标签?并且此(elixir.ematia.de/trac/wiki/Recipes/TagCloud)配方中使用的方法似乎只允许每个项目使用一个标签。哪些资源最适合阐明该主题?我也读过这篇文章(dev.mysql.com/tech-resources/articles/…),但是无法想象如何管理多个标签。
加里·奥尔德伯

2
正如我所说,您需要两个表。基本上,它只是典型的多对多关系,因此您可以按照SQLAlchemy的指南进行操作:sqlalchemy.org/docs/… 您将拥有一个tags表,用于存储标记名称和其他标记信息,并且还将具有一个task_tags表,其中对于添加到任务的每个标签,将有一条记录。因此带有2个标签的任务在task_tags表中将只有2条记录。
Daniel Kluev 2010年

11

除了上述答案外,无论谁在寻找解决方案,您都可以尝试使用“匹配”运算符而不是“喜欢”。不想被偏见,但它在Postgresql中对我来说非常有效。

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

它继承了CONTAINSMATCH之类的数据库功能。但是,它在SQLite中不可用。

有关更多信息,请转到通用过滤器运算符


8
这两个运算符有什么区别?
buhtz

@buhtz取决于您的数据库后端请参见SQL-炼金术文档:docs.sqlalchemy.org/en/14/core/...在Postgres的你to_tsquery可以让你添加文字运营商喜欢的东西ORAND postgresql.org/docs/current/...
尼克

7

试试这个代码

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


0

如果您使用本机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()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.