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—查询
如何拥有一个包含数千个表的数据库,这些表具有不同数量的列,这些列在 Django / SQLAlchemy ORM 中都是同一类?