SQLAlchemy操作Query对象时是否会触发额外数据库查询请求?
SQLAlchemy 查询执行逻辑相关疑问
我是SQLAlchemy初学者,针对自己编写的如下代码存在执行逻辑层面的疑问:
query = db.query(Purchase.name, func.sum(Purchase.price).label('total'), func.count(Purchase.name).label('count')) if date_start and date_end: query = query.filter(Purchase.date >= date_start, Purchase.date <= date_end) query = query.group_by(Purchase.name)\ .order_by(sqlalchemy.desc('total'))[:limit] result = [ItemDict(name=item.name, total=item.total, count=item.count) for item in query]
我对代码执行逻辑有以下两点判断,想确认是否正确:
- 上述程序运行全程仅会向数据库发起1次查询请求?
- 操作Query对象的过程中不会产生额外数据库请求,即上述列表推导式遍历query的逻辑不会触发额外查询?
解答
你的两点理解全部正确,具体逻辑说明如下:
- SQLAlchemy的
Query对象采用懒加载设计,在真正触发结果执行前,所有filter()、group_by()、order_by()、切片[:limit]操作都只是在内存中拼接SQL的构造逻辑,不会和数据库产生任何交互。只有当你第一次迭代访问query(也就是代码里列表推导式循环取元素的环节),才会把拼接完成的完整SQL发送到数据库执行,整个流程只会发起这1次数据库请求。 - 本次遍历过程不会产生额外查询:你的查询直接返回的是字段值和聚合计算结果,不是挂载了关联关系的ORM实体对象,不存在访问关联字段触发懒加载的场景,遍历过程中读取
name、total、count都是直接从已经取回的结果集中取值,不会再向数据库发送额外请求。
内容的提问来源于stack exchange,提问作者Maksim Burtsev
相关产品推荐
相关产品推荐

