在软件开发中,数据库查询是最常见的操作之一,但如何编写高效、可读且健壮的查询代码却是一门艺术。
原始代码片段如下:
app = db.session.query(App).filter(App.id == workflow_provider.app_id).first()
if app is None or app.workflow_id is None:
raise ToolProviderNotFoundError(f"workflow provider {provider_id} not found")
这段代码的功能是查询一个 App 记录,并检查该记录是否存在以及其 workflow_id 是否为空。虽然功能正确,但从多个方面来看都有优化空间。
第一个优化点是将workflow_id is None
的判断从 Python 代码移到 SQL 查询中:
app = (
db.session.query(App)
.filter(
App.id == workflow_provider.app_id,
App.workflow_id.isnot(None)
)
.first()
)
为什么这样更好?
数据库层面过滤:在数据库层面就过滤掉不符合条件的记录,减少了不必要的数据传输。数据库引擎优化了查询执行,通常比在应用层过滤更高效。
减少 Python 处理:避免了在 Python 中处理不符合条件的记录,减少了内存使用和 CPU 时间。
原子性操作:查询条件更加完整地表达了业务逻辑,使代码意图更清晰。
在 SQLAlchemy 中,isnot(None)
是推荐的写法,而不是 Python 中的is not None
:
App.workflow_id.isnot(None) # 优于 App.workflow_id is not None
这是因为:
原始代码使用了if app is None or app.workflow_id is None
,而优化后可以简化为:
if not app:
raise ToolProviderNotFoundError(f"Workflow provider {provider_id} not found")
这种简化基于以下考虑:
if not app
在 Python 中与if app is None
对于查询结果判断是等价的将错误消息中的"workflow"改为首字母大写:
f"Workflow provider {provider_id} not found"
虽然是小改动,但体现了:
进一步优化可以使用 SQLAlchemy 2.0 风格的查询:
from sqlalchemy import select
app = db.session.execute(
select(App).where(
App.id == workflow_provider.app_id,
App.workflow_id.isnot(None)
)
).scalar_one_or_none()
这种写法的优势包括:
select()
和where()
方法分离,语义更明确execute()
方法scalar_one_or_none()
明确表达了期望单个结果或 None觉得有用的话点个赞
呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!
Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!