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

求助:将含unnest与ilike的SQL转换为SQLAlchemy语句

用SQLAlchemy实现PostgreSQL数组列的模糊匹配查询

需求:查询books表中,categories字符串数组列至少包含一个以fiction开头元素的所有记录。

前提假设

假设你已经定义了对应的SQLAlchemy模型:

from sqlalchemy import Column, Integer, String, ARRAY
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer, primary_key=True)
    categories = Column(ARRAY(String))
    # 其他业务列...

方法1:对应原SQL的EXISTS+UNNEST实现

直接将你提供的原生SQL逻辑转换为SQLAlchemy查询:

from sqlalchemy import select, func, exists

# 构造子查询:展开数组并过滤匹配项
subquery = select(func.unnest(Book.categories).label('categories')).where(
    func.unnest(Book.categories).ilike('fiction%')
).alias('x')

# 主查询:通过EXISTS筛选符合条件的书籍
query = select(Book).where(exists(subquery))

或者更紧凑的写法:

query = select(Book).where(
    exists(
        select(func.unnest(Book.categories)).where(
            func.unnest(Book.categories).ilike('fiction%')
        )
    )
)

方法2:使用PostgreSQL数组ANY操作符(更简洁)

你提到的简易查询可以修正为合法的PostgreSQL语法,对应SQLAlchemy的实现更简洁:

from sqlalchemy import select, array

# 方式A:直接使用ILIKE ANY数组
query = select(Book).where(Book.categories.ilike(array(['fiction%'])))

# 方式B:使用SQLAlchemy的any()方法
query = select(Book).where(Book.categories.any(ilike='fiction%'))

这两种写法生成的原生SQL类似于:

SELECT books.id, books.categories 
FROM books 
WHERE books.categories ILIKE ANY (ARRAY['fiction%'])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:08:16