You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用SQLAlchemy结合LIKE查询JSONB列表中的值?

在SQLAlchemy中对JSONB数组进行类LIKE的模糊查询

嘿,这个需求我之前刚好碰到过!SQLAlchemy本身没有直接提供像contains_like('%app%')这种一键式的方法,但结合PostgreSQL的原生JSONB函数,完全能实现你要的效果——检查JSONB数组里是否存在包含指定子串的元素。

下面给你两种实用的实现方式,根据你的PostgreSQL版本选就行:

方法1:展开数组后匹配(兼容所有支持JSONB的PostgreSQL版本)

这种方法的思路是把JSONB数组拆成单个元素,对每个元素做文本模糊匹配,最后去重得到符合条件的行:

from sqlalchemy import select, func
from your_models import Basket  # 替换成你实际的模型类

# 构建查询语句
query = select(Basket).distinct().where(
    # 把fruits数组展开成单个元素,转成文本后做LIKE匹配
    func.jsonb_array_elements(Basket.fruits).astext.like("%app%")
)

# 执行查询获取结果
results = db_session.execute(query).scalars().all()

这里的jsonb_array_elements是PostgreSQL的原生函数,负责把JSONB数组拆成多行;.astext用来把JSONB类型的元素转换成文本,这样才能用like做模糊匹配;distinct()是为了避免因为数组展开成多行后,同一行数据被多次返回。

方法2:用JSON路径查询(PostgreSQL 12+推荐)

如果你的PostgreSQL版本是12或更高,用JSON路径查询会更简洁高效:

from sqlalchemy import select, func, text
from your_models import Basket

query = select(Basket).where(
    func.jsonb_path_query_exists(
        Basket.fruits,
        # JSON路径表达式:检查数组中是否有元素包含"app"子串
        text('$[*] ? (@ like "%app%")')
    )
)

results = db_session.execute(query).scalars().all()

解释一下路径表达式:$[*]表示匹配数组中的所有元素,@ like "%app%"表示当前元素要满足包含"app"的模糊匹配条件。jsonb_path_query_exists会直接返回布尔值,判断是否存在符合条件的元素,不需要额外去重。

最后提醒下:这两种方法都依赖PostgreSQL的JSONB特性,如果你的数据库不是PostgreSQL,可能需要换成对应数据库的JSON处理函数,但核心思路是一致的——要么展开数组匹配,要么用路径查询做批量检查。

内容的提问来源于stack exchange,提问作者john

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:35:09