在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法有啥区别?
Posted
技术标签:
【中文标题】在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法有啥区别?【英文标题】:In SQLAlchemy what is the difference between the "filter" vs "join and filter" syntax?在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法有什么区别? 【发布时间】:2019-05-01 02:12:00 【问题描述】:更具体地说,我看到很多人没有在 SQLAlchemy 中使用自然的类似 SQL 的连接语法,而是倾向于使用过滤器来进行连接。在这里详细说明我将如何加入:
(session.Query(Book)
.join(Author, Publisher, Retailer)
.filter(
Author.name == "Crenshaw Adams",
Publisher.country == "United States",
Retailer.is_online == True))
连接列隐含在模型声明文件中定义的关系中。
但在其他任何地方(尤其是在 *** 上)我都看到人们这样做:
(session.Query(Book)
.filter(
Book.author_id == Author.id,
Author.publisher_id == Publisher.id,
Publisher.retailer_id == Retailer.id,
Author.name == "Crenshaw Adams",
Publisher.country == "United States",
Retailer.is_online == True
))
以下哪种方法是正确的方法?哪个更 Pythonic?或者,至少,应该使用 SQLAlchemy 的方式更惯用?并且在DB资源使用方面,还是本地机器资源使用方面有区别(即DB的CPU和RAM压力更大,本地机器压力更小,反之亦然)?
此外,前一种方式不允许查询 API 上的 update()
方法 - 它抱怨不允许多表更新 - 即使我只更新一个表。后者允许update()
正常工作。
【问题讨论】:
【参考方案1】:主要区别在于前者导致查询使用SQL-92JOIN
语法,而后者使用较旧的语法——例如,有些人出于习惯更喜欢它。两者都是正确的方法,并且与代码是否为 Pythonic 没有太大关系。同样在我看来,SQLAlchemy 中两者都不是更惯用的,尽管Query.join()
可以很好地与定义的外键关系和 ORM 关系配合使用,正如您自己所指出的那样。它们还应该在现代 SQL DBMS 中产生相同的执行计划,因此在资源使用等方面没有有意义的差异。
至于Query.update()
不支持显式连接,不同的SQL DBMS对多表更新的支持不同,语法和方法也不同。有些允许显式连接,有些不允许,还有some allow updating through subqueries。当前的实现似乎是一种折衷方案,并将呈现给正在使用的 DBMS 的合适的 UPDATE
语句。
【讨论】:
以上是关于在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
SQLAlchemy:如何在连接查询中的过滤器之前应用 distinct
如何在 sqlalchemy 查询过滤器中使用用户定义的 python 函数?