SQLAlchemy ORM:修改查询返回的列

Posted

技术标签:

【中文标题】SQLAlchemy ORM:修改查询返回的列【英文标题】:SQLAlchemy ORM: modify the columns returned from a query 【发布时间】:2012-05-20 21:49:05 【问题描述】:

如果我有一个 SQLAlchemy ORM 查询:

admin_users = Session.query(User).filter_by(is_admin=True)

是否可以修改该查询返回的列?

例如,我可以只选择User.id 列,并在子查询中使用它:

admin_email_addresses = Session.query(EmailAddress)\
    .filter(EmailAddress.user_id.in_(admin_users.select_columns(User.id))

注意:.values() 方法将不起作用,因为它执行查询并返回一个可迭代的结果(例如,EmailAddress.user_id.in_(admin_users.values(User.id)) 将执行两个查询,而不是一个)。

我知道我可以将第一个查询修改为 Session.query(User.id),但我特别想知道如何修改查询返回的列。

【问题讨论】:

【参考方案1】:

我感觉到你对values() 的痛苦。在 0.6.5 中,我添加了 with_entities(),这就像 values() 一样,除了不迭代:

q = q.with_entities(User.id)

【讨论】:

【参考方案2】:

假设您的Address.user_id 定义了ForeignKey,与IN 运算符相比,下面的查询将更有效地完成这项工作:

admin_email_addresses = session.query(EmailAddress).\
    join(User).filter(User.is_admin==True)

如果您没有 ForeignKey(尽管您应该),您可以明确指定 join 条件:

admin_email_addresses = session.query(EmailAddress).\
    join(User, User.id==EmailAddress.user_id).filter(User.is_admin==True)

但如果你真的想用in_ 操作符来做这件事,那么你就去吧(注意subquery):

subq = session.query(User.id).filter(User.is_admin==True).subquery()
admin_email_addresses = session.query(EmailAddress).\
       filter(EmailAddress.user_id.in_(subq)) 

【讨论】:

确实,在我提供的示例中,JOIN 是正确的解决方案。但是,由于它没有解决我实际提出的问题,我将接受 zzzeek 的回答。

以上是关于SQLAlchemy ORM:修改查询返回的列的主要内容,如果未能解决你的问题,请参考以下文章

在身份映射之外强制使用 sqlalchemy ORM get()

tornado 07 数据库—ORM—SQLAlchemy—查询

SQLAlchemy ORM如何将查询与表连接起来

sqlalchemy使用之查询指定的列

如何拥有一个包含数千个表的数据库,这些表具有不同数量的列,这些列在 Django / SQLAlchemy ORM 中都是同一类?

SQLAlchemy 将外连接 ORM 查询转换为 Core