更具体地说,我看到很多人不使用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的方式更惯用了?在数据库资源使用或本地计算机资源使用方面是否存在差异(即,对DB的CPU和RAM的压力较大,而对本地计算机的压力较小,反之亦然)?
此外,前一种方法不允许Query API上的update()
方法-它抱怨不允许多表更新-即使我只更新一个表。后者允许update()
正常工作。
答案 0 :(得分:2)
主要区别在于,前者导致查询使用SQL-92 JOIN
语法,而后者则使用较旧的语法–例如,有些人出于习惯而不喜欢它。两者都是正确的方法,两者都与是否使用Python语言无关。我还认为,尽管Query.join()
与定义的外键关系和ORM关系很好地配合使用,但在SQLAlchemy中也没有什么习惯,就像您自己指出的那样。在现代SQL DBMS中,它们还应导致相同的执行计划,因此在资源使用等方面没有有意义的区别。
对于Query.update()
不支持显式连接的情况,不同的SQL DBMS对不同表的支持不同,语法和方法也不同。有些允许显式联接,有些不允许,some allow updating through subqueries。当前的实现似乎是一个折衷方案,它将为正在使用的DBMS提供适当的UPDATE
语句。