SQLAlchemy选择API和查询API之间的区别

16

不确定之前是否有人问过,但在SQLAlchemy的文档中,他们谈论了将select()引入作为ORM的新2.0样式的一部分。

之前(1.x样式),使用query()方法获取数据。

这两者之间有什么区别?

例如,对于查询带有电子邮件和姓名的Users表中的用户,我们可以在Query API中执行以下操作:

session.query(Users).filter_by(name='name', email='mail@example.com').first()

在 Select API 中,这会导致更多的代码:

from sqlalchemy import select

query = select(Users).filter_by(name='name', email='mail@example.com')
user = session.execute(query).fetchone()

相比较而言,它们之间是否有明显的优势,例如性能提升? 2.0 API仍在积极开发中,但似乎它们的文档更倾向于选用API,而非“传统”的查询API。这是试图弥合ORM和核心功能之间的差距吗?

2个回答

14
最大的区别在于如何构建select语句。新方法创建了一个更加动态的select对象,可以通过其他的select语句构建,而无需显式地定义子查询:

# select from a subqeuery styled query
q = select(Users).filter_by(name='name', email='mail@example.com')
q = select(Users.name, Users.email).select_from(q)

最新的selectable API使查询的“本地sql”构建更加方便。可以在多种功能中定义并传递查询,如where子句、having、select_from、intersect、union等。

就性能而言,在Python运行时间上可能会有轻微的好处(查询编译),但与网络延迟和数据库工作相比可以忽略不计。

顺便说一句,这是个好问题!我的回答是基于我使用select API的经验。我很想听听别人的看法。


2
我完全支持这个最后的声明 - 我刚好遇到了同样的问题,真的很期待更多关于这个问题的信息。感谢您的回复! - Robert
此外,2.0版本的一个重大变化是深度集成类型提示(PEP 484),这应该使在使用IDE时开发更加容易。 - Adrian B.

5
自从 SQLAlchemy 1.4 版本开始,query() 已经通过 select() API 实现,因此在性能方面应该没有太大的区别。
在版本 1.4 中,所有 Core 和 ORM SELECT 语句都直接从 Select 对象呈现;当使用 Query 对象时,在语句调用时,它将其状态复制到 Select 中,然后使用 2.0 风格执行内部调用。

https://docs.sqlalchemy.org/en/14/changelog/migration_14.html#change-5159

历史上,query() 和 select() 的区别在于 query() 用于 ORM,而 select() 用于 Core。版本2.0消除了ORM和Core之间的许多差异,并使它们更加统一。现在比较select()和query()没有太多意义。
虽然存在一些向后兼容性,你并不需要立即采用2.0风格,但我认为开始采用它是明智的,无论是在1.4还是2.0中。我已经这样做了一段时间,发现很容易习惯,并且很快就比1.x风格更直观。但是我只使用SQLAlchemy约一年,对原生SQL有更多年的经验。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接