在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法之间有什么区别?

2024-01-20

更具体地说,我发现很多人倾向于使用过滤器来进行连接,而不是在 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 压力更大,本地计算机压力较小,反之亦然)?

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


主要区别在于,前者产生的查询使用SQL-92 https://en.wikipedia.org/wiki/SQL-92 JOIN语法,而后者使用旧的语法——例如,有些人出于习惯而喜欢它。两者都是正确的方法,并且与代码是否 Pythonic 没有太大关系。另外,在我看来,这两种方法在 SQLAlchemy 中都不是更惯用的,不过Query.join() https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.join正如您自己所指出的,它可以很好地处理已定义的外键关系和 ORM 关系。它们还应该在现代 SQL DBMS 中产生相同的执行计划,因此在资源使用等方面没有有意义的差异。

As to Query.update() https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.update由于不支持显式连接,不同的 SQL DBMS 对多表更新的支持不同,语法和方法也不同。有些允许显式连接,有些则不允许,并且有些允许通过子查询更新 https://stackoverflow.com/questions/42613777/sqlalchemy-correlated-update-with-multiple-columns。当前的实现似乎是一种妥协,并将呈现为合适的UPDATE正在使用的 DBMS 的语句。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 SQLAlchemy 中,“过滤器”与“连接和过滤器”语法之间有什么区别? 的相关文章

随机推荐