必须避免在 view 里写 sql,因其破坏可维护性与安全性:易引发 sql 注入、耦合 http 与业务逻辑、事务失控、多处重复且难以统一维护。

直接在 View 里写 SQL 语句会立刻破坏数据层的可维护性和安全性,不是“不推荐”,而是生产环境里必须避免。
SQL 注入风险几乎无法规避
哪怕你记得用 db.session.execute() 配参数化查询,只要逻辑混在视图函数里,就容易在后续修改中被替换成 f"SELECT * FROM users WHERE id = {user_id}" 这类拼接——而这类错误不会报语法错,只会在某次用户输入单引号时突然爆库。
- Flask 自身不拦截字符串拼接 SQL,ORM 的安全机制(如参数绑定)只在明确走
session.query()或text()+params时生效 - 模板里渲染 raw SQL、日志里打印未脱敏 SQL、异常回溯暴露查询语句,都会放大攻击面
业务逻辑和 HTTP 协议耦合死
View 函数本该只处理请求解析、权限校验、响应组装。一旦里面塞了 conn.execute("UPDATE ..."),你就没法复用这段逻辑到 CLI 命令、后台任务或 API v2 接口里。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 比如“冻结用户”操作,在 Web 请求里要校验登录态,在定时任务里要按条件批量执行,在管理命令里要手动指定 ID——三处代码若都重写 SQL,改字段名时就得改三次
-
request.args.get('status')和数据库字段user.status直接耦合,前端传错值(如"actvie")就会静默失败,而不是抛出明确校验异常
事务边界失控导致数据不一致
View 层通常对应一次 HTTP 请求,但一个请求里可能触发多个数据库操作。如果每个操作都独立 commit,就丧失了 ACID 中的原子性。
- 转账场景:
sender.balance -= 100和receiver.balance += 100必须包裹在同一事务里;分开写 SQL 容易漏掉rollback或误提前commit - Flask-SQLAlchemy 默认每个请求结束自动 commit(若开启
SQLALCHEMY_COMMIT_ON_TEARDOWN=True),但你手写的原生 SQL 不受这个控制,事务状态完全不可预测 - 多表更新时,ORM 的
session.flush()能保证外键约束检查时机,而原生 SQL 无法触发这一层校验
真正麻烦的不是“写 SQL 难”,而是当项目加到 5 个接口、3 种角色、2 套数据库时,那些散落在 views.py 里的 SQL 会变成没人敢动的雷区——连加个软删除条件都要 grep 全局,生怕漏掉某处硬编码的 WHERE deleted=0。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










