更具体地说,我看到很多人倾向于使用过滤器来进行连接,而不是在 SQLAlchemy 中使用类似 SQL 的自然连接语法。详细说明我将如何加入:
(session.Query(Book)
.join(Author, Publisher, Retailer)
.filter(
Author.name == "Crenshaw Adams",
Publisher.country == "United States",
Retailer.is_online == True))
连接列隐含在模型声明文件中定义的关系中。
但是在其他地方(尤其是在 StackOverflow 上)我看到人们这样做:
(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 的方式更加惯用?在数据库资源使用或本地机器资源使用方面是否存在差异(即,一个对数据库的 CPU 和 RAM 的压力更大,对本地机器的压力更小,反之亦然)?
此外,前一种方法不允许在查询 API 上使用 update()
方法 - 它提示不允许多表更新 - 即使我只更新一个单表。后者允许 update()
正常工作。
最佳答案
主要区别在于前者导致使用 SQL-92 的查询JOIN
语法,而后者使用较旧的语法——例如,出于习惯,有些人更喜欢它。两者都是正确的方法,与代码是否为 Pythonic 无关。同样在我看来,在 SQLAlchemy 中两者都不是更惯用的,尽管 Query.join()
正如您自己指出的那样,可以很好地处理定义的外键关系和 ORM 关系。它们还应该在现代 SQL DBMS 中产生相同的执行计划,因此在资源使用等方面没有有意义的差异。
至于Query.update()
不支持显式连接,不同的 SQL DBMS 对多表更新有不同的支持,具有不同的语法和方法。有些允许显式连接,有些不允许,并且 some allow updating through subqueries .当前的实现似乎是一种妥协,将为正在使用的 DBMS 呈现合适的 UPDATE
语句。
关于python - 在 SQLAlchemy 中, "filter"与 "join and filter"语法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531826/