查询我的数据库时,我只想加载指定的列。使用Include
创建查询需要引用模型列属性,而使用with_entities
创建查询时需要与列名对应的字符串。我更喜欢使用load_only
,因为使用字符串创建动态查询更容易。两者有什么区别?
答案 0 :(得分:14)
存在一些差异。丢弃不需要的列(如问题中)最重要的一点是使用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()
可以添加或删除(简单地说:替换)模型或列;您甚至可以使用它来修改查询,用您自己的函数替换所选实体,如func.count()
:
query = User.query
count_query = query.with_entities(func.count(User.id)))
count = count_query.scalar()
请注意,生成的查询与query.count()
不同,后者可能会更慢 - at least in 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()