SQLAlchemy中的with_entities和load_only有什么区别?

Luk*_*ine 10 python sqlalchemy

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

load_only文档

with_entities文档

kra*_*ski 20

有一些差异.丢弃不需要的列(如问题中)最重要的一点是,使用load_only仍然会导致创建对象(模型实例),而使用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)]  
Run Code Online (Sandbox Code Playgroud)

LOAD_ONLY

load_only()推迟从模型中加载特定列.它从查询中删除 .您仍然可以稍后访问所有其他列,但只有在您尝试访问它们时才会执行其他查询(在后台).

当您在数据库中存储用户图片之类的内容但不想浪费时间在不需要时传输图像时,"仅加载"非常有用.例如,当显示用户列表时,这可能就足够了:

User.query.options(load_only('name', 'fullname'))
Run Code Online (Sandbox Code Playgroud)

with_entities

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

query = User.query
count_query = query.with_entities(func.count(User.id)))
count = count_query.scalar()
Run Code Online (Sandbox Code Playgroud)

请注意,生成的查询不一样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()
Run Code Online (Sandbox Code Playgroud)