
在 SQLAlchemy ORM 中,可通过 sqlalchemy.all_() 函数实现 PostgreSQL LIKE ALL 的等效逻辑,避免使用原生 SQL,同时确保所有通配符模式均被匹配。
在 sqlalchemy orm 中,可通过 `sqlalchemy.all_()` 函数实现 postgresql `like all` 的等效逻辑,避免使用原生 sql,同时确保所有通配符模式均被匹配。
在 PostgreSQL 中,column LIKE ALL (ARRAY['%a%', '%b%', '%c%']) 表示目标字段需同时满足所有 LIKE 模式(即每个模式都必须匹配),这不同于 OR 逻辑的多次 like() 调用,也区别于 IN 或 CONTAINS 等语义。SQLAlchemy 自 2.0 起正式支持该语法,核心在于使用 sqlalchemy.all_() 与 like() 组合。
✅ 正确用法示例
from sqlalchemy import all_, select
from sqlalchemy.orm import Session
# 假设已定义模型 OutBoxDocument
statement = select(OutBoxDocument).where(
OutBoxDocument.document_summary.like(all_(["%par1%", "%par2%", "%par3%"]))
)
with Session(engine) as session:
results = session.scalars(statement).all()
该语句生成的标准 SQL 为:
SELECT outbox_document.id, outbox_document.document_summary FROM outbox_document WHERE outbox_document.document_summary LIKE ALL (%(param_1)s)
其中 %(param_1)s 对应传递的字符串列表(如 ['%par1%', '%par2%', '%par3%']),由 SQLAlchemy 自动绑定为 PostgreSQL 数组参数。
⚠️ 注意事项
- 仅适用于 PostgreSQL:LIKE ALL 是 PostgreSQL 特有语法,MySQL、SQLite、SQL Server 等不支持;若需跨数据库兼容,请改用链式 and_() + 多个 like()(但语义不同:LIKE '%a%' AND LIKE '%b%' AND LIKE '%c%' 实际等价于 LIKE ALL,注意这不是严格等价——前者是逐个子串匹配,后者是数组元素级匹配;不过在绝大多数业务场景中,二者效果一致,且更通用)。
- 通配符需手动添加:all_() 接收的是完整 pattern 字符串(如 "%par1%"),不自动补 %,务必自行处理。
-
Flask-SQLAlchemy 用户:直接替换 Session(engine) 为 db.session 即可:
results = db.session.scalars(statement).all()
-
性能提示:LIKE 配合前导通配符(如 %par)无法使用 B-tree 索引,建议对高频模糊搜索字段建立 pg_trgm 扩展索引以提升性能:
CREATE INDEX idx_doc_summary_trgm ON outbox_document USING GIN (document_summary gin_trgm_ops);
? 替代方案(跨数据库兼容)
若需适配非 PostgreSQL 数据库,可退化为显式逻辑组合:
from sqlalchemy import and_ patterns = ["%par1%", "%par2%", "%par3%"] conditions = [OutBoxDocument.document_summary.like(p) for p in patterns] statement = select(OutBoxDocument).where(and_(*conditions))
此写法生成 WHERE ... LIKE ? AND ... LIKE ? AND ...,语义上与 LIKE ALL 在多数场景下一致,且完全兼容各主流方言。
总之,like(all_(...)) 是 SQLAlchemy 对 PostgreSQL LIKE ALL 的标准 ORM 封装,简洁、安全、符合规范,是替代原生 SQL 的首选方案。










