2012-05-20 24 views
8

返回如果我有一個ORM SQLAlchemy的查詢中的列: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),但我特別想知道如何修改查詢返回的列。

回答

16

我覺得你的痛苦在values()的事情。在0.6.5我加with_entities()這類似,只是不重複values()

q = q.with_entities(User.id) 
1

假設你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)) 
+0

這是真的,我在所提供的例子,一個'JOIN'是正確的解決方案。然而,由於它沒有解決我實際問到的問題,我將接受zzzeek的答案。 –

+0

@DavidWolever:夠公平的 – van