SQLAlchemy 中 with_entities 和 load_only 有什么区别?

45

查询数据库时,我只想加载指定的列。使用 with_entities 创建查询需要引用模型列属性,而使用 load_only 创建查询需要一个与列名对应的字符串。我更喜欢使用 load_only ,因为使用字符串创建动态查询更容易。这两者之间有什么区别?

load_only 文档

with_entities 文档


有点相关:https://dev59.com/fWgu5IYBdhLWcg3wK0Cr - Ilja Everilä
1个回答

77

有几个区别。当丢弃不需要的列时(如问题所示),最重要的区别是使用 load_only 仍会创建一个对象(即一个 Model 实例),而使用 with_entities 只会得到所选列的值的元组。

>>> query = User.query
>>> query.options(load_only('email', 'id')).all()
[<User 1 using e-mail: n@d.com>, <User 2 using e-mail: n@d.org>]
>>> query.with_entities(User.email, User.id).all()
[('n@d.org', 1), ('n@d.com', 2)]  

仅加载特定列

load_only() 可以推迟从模型中加载特定的列。它会从查询中删除这些列。你仍然可以稍后访问所有其他列,但是只有在访问它们时才会执行额外的查询(在后台)。

"仅加载" 在您将用户图片之类的内容存储在数据库中,但不希望在不需要它们时浪费传输时间时非常有用。例如,在显示用户列表时,可能只需要使用这个功能:

User.query.options(load_only('name', 'fullname'))

with_entities

with_entities() 可以添加或删除(简单来说:替换)模型;您甚至可以使用它来修改查询,使用自己的函数(例如 func.count())替换所选实体:

query = User.query
count_query = query.with_entities(func.count(User.id)))
count = count_query.scalar()
请注意,生成的查询结果与 query.count() 不同,后者可能比较慢 - 至少在 MySQL 中(因为它会生成一个子查询)。 with_entities 的另一个额外功能的例子是:
query = (
    Page.query
    .filter(<a lot of page filters>)
    .join(Author).filter(<some author filters>)
)
pages = query.all()

# ok, I got the pages. Wait, what? I want the authors too!
# how to do it without generating the query again?

pages_and_authors = query.with_entities(Page, Author).all()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接