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

时间:2017-11-09 01:26:03

标签: python sqlalchemy

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

load_only documentation

with_entities documentation

1 个答案:

答案 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

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()不同,后者可能会更慢 - 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()