【问题标题】:SQLAlchemy ORM: modify the columns returned from a querySQLAlchemy ORM:修改查询返回的列
【发布时间】: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),但我特别想知道如何修改查询返回的列。

【问题讨论】:

    标签: python orm sqlalchemy


    【解决方案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 的回答。
      猜你喜欢
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 2017-03-21
      • 1970-01-01
      • 2020-02-17
      • 2021-09-21
      相关资源
      最近更新 更多