更具体地说,我看到很多人没有使用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的压力更大,而对本地计算机的压力更小,反之亦然)?
另外,前一种方法不允许update()Query API上的方法-即使无法只更新一个表,它也会抱怨不允许多表更新。后者允许update()正常工作。
update()
主要区别在于,前者会导致查询使用SQL-92 JOIN语法,而后者会使用较旧的语法- 例如,有些人出于习惯而不喜欢它。两者都是正确的方法,两者都与是否使用Python语言无关。我还认为,SQLAlchemy也不是惯用语言,但Query.join()正如您所指出的那样,它与定义的外键关系和ORM关系很好地配合使用。在现代SQL DBMS中,它们还应导致相同的执行计划,因此资源使用等方面没有有意义的区别。
JOIN
Query.join()
关于Query.update()不支持显式联接的问题,不同的SQL DBMS对具有不同语法和方法的多个表更新具有不同的支持。有些允许显式连接,有些则不允许,有些则允许通过子查询进行更新。当前的实现似乎是一个折衷方案,并且将为UPDATE使用中的DBMS提供适当的声明。
Query.update()
UPDATE