
flask-sqlalchemy 3.0 废弃了旧版的 `query` 属性,推荐使用模型类直接调用 `select()` 配合 `session.execute()`,但兼容层仍支持 `model.query`;模糊搜索应优先使用 `contains()` 方法替代 `like('%...%')`,简洁且可读性更强。
在 Flask-SQLAlchemy 3.0 中,虽然为向后兼容仍保留 Model.query 接口(即 Posts.query),但其底层已基于 SQLAlchemy 2.0+ 的新执行模型重构。因此,原 Flask-SQLAlchemy 2.x 中常见的链式 filter(...).order_by(...).all() 写法依然可用,但推荐逐步迁移至更现代、显式可控的查询风格。
✅ 推荐写法(兼容且语义清晰)
# 使用 contains() —— 简洁、安全、自动处理转义(相比手动拼接 '%' + ... + '%')
search_results = Posts.query.filter(
Posts.content.contains(post_searched_form)
).order_by(Posts.title).all()⚠️ 注意:contains() 默认区分大小写(依赖数据库 collation)。若需忽略大小写,可改用 ilike()(PostgreSQL)或 func.lower() 组合: from sqlalchemy import func
跨数据库兼容的不区分大小写搜索
search_results = Posts.query.filter( func.lower(Posts.content).contains(func.lower(post_searched_form)) ).order_by(Posts.title).all()
### ? 迁移至 SQLAlchemy 2.0+ 原生风格(推荐长期采用)
```python
from sqlalchemy import select
stmt = select(Posts).where(
Posts.content.contains(post_searched_form)
).order_by(Posts.title)
search_results = db.session.execute(stmt).scalars().all()其中 db 是你的 SQLAlchemy 实例(如 db = SQLAlchemy(app))。该方式完全脱离 query 属性,符合 Flask-SQLAlchemy 3.0 的设计导向,也便于未来升级和单元测试。
? 小结
- contains() 是 like('%value%') 的语义等价替代,更安全、更易读;
- Posts.query 在 3.0 中仍可用,但属兼容层,官方文档已倾向引导使用 select();
- 模糊搜索务必注意大小写与 SQL 注入风险——contains() 自动参数化,无需手动格式化字符串;
- 生产环境建议统一使用 func.lower() 或数据库特定函数(如 ilike)实现无感匹配。
通过以上调整,你既能平滑过渡到 Flask-SQLAlchemy 3.0,又能写出更健壮、可维护的查询逻辑。










