【问题标题】: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))

连接列隐含在模型声明文件中定义的关系中。

但在其他任何地方(尤其是在 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资源使用方面,还是本地机器资源使用方面有区别(即DB的CPU和RAM压力更大,本地机器压力更小,反之亦然)?

此外,前一种方式不允许查询 API 上的 update() 方法 - 它抱怨不允许多表更新 - 即使我只更新一个表。后者允许update() 正常工作。

【问题讨论】:

    标签: python sql postgresql sqlalchemy


    【解决方案1】:

    主要区别在于前者导致查询使用SQL-92JOIN 语法,而后者使用较旧的语法——例如,有些人出于习惯更喜欢它。两者都是正确的方法,并且与代码是否为 Pythonic 没有太大关系。同样在我看来,SQLAlchemy 中两者都不是更惯用的,尽管Query.join() 可以很好地与定义的外键关系和 ORM 关系配合使用,正如您自己所指出的那样。它们还应该在现代 SQL DBMS 中产生相同的执行计划,因此在资源使用等方面没有有意义的差异。

    至于Query.update()不支持显式连接,不同的SQL DBMS对多表更新的支持不同,语法和方法也不同。有些允许显式连接,有些不允许,还有some allow updating through subqueries。当前的实现似乎是一种折衷方案,并将呈现给正在使用的 DBMS 的合适的 UPDATE 语句。

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 2019-02-11
      • 2015-04-18
      • 2015-11-15
      • 1970-01-01
      • 2019-03-12
      • 2016-10-27
      • 2012-04-15
      • 2016-03-05
      相关资源
      最近更新 更多