2015-06-03 47 views
1

我有一個User模型,主鍵user_id和一個獨特的username。如果我知道user_id,我使用session.query(User).get(user_id)。什麼是該屬性不是主鍵時的等效查詢,如session.query(User).get(username=username)什麼是通過非主鍵屬性查詢的慣用方式?

session.query(User).filter_by(username=username).first()如果找不到行,還會返回None,但並未明確說明該查詢永遠不會有多於一行。

我寫了下面的內容,但是這是任何人經常在代碼中作爲助手實現的東西嗎?

try: 
    user = session.query(User).filter_by(username=username).one() 
except (NoResultFound, MultipleResultsFound): 
    user = None 
+0

不,你的回答沒有幫助@davidism。你改變了我的問題以符合你的答案。我並不是在尋找一種「便捷的方式來實現這個」,我已經爲你編輯過的東西提供了一個解決方案。我要求的是在這種情況下的常見做法。 – Oin

+2

我認爲你需要解釋爲什麼你需要明確說明不能有多行。明確給誰? –

+1

@Oin我更新了我的答案,希望能夠回答你的直接問題,請澄清你的問題,如果這不是你問的問題。 – davidism

回答

1

的「習慣」的方式來查詢一個就是用filterfirstoneget基本上是主鍵的快捷方式。如果你所要求的是「這個嘗試/接受塊可以使用」,那麼是的,它會正常工作,沒有人會覺得很難理解。

什麼有點混淆返回None如果有多個結果,但如果這就是你所需要的那麼工作。鑑於username列已經有一個唯一的約束,無論如何這種方法幾乎沒有用,因爲永遠不會有多個用戶名結果。


可重用解決方案是使用一個定製Query子類,並添加一個one_or_none方法其功能類似於one。創建會話時,通過傳遞query_cls來使用這個類。

from sqlalchemy.orm import Query 
from sqlalchemy.orm.exc import MultipleResultsFound 

class MyQuery(Query): 
    def one_or_none(self): 
     """Return one result, or None if there are zero or >1 results.""" 
     ret = list(self) 
     r_len = len(ret) 

     if r_len == 1: 
      return ret[0] 
     else: 
      return None 

session = Session(query_cls=MyQuery) 
session.query(User).filter(username=username).one_or_none() 

同樣,當有未返回多個結果是不是一個典型的行爲,這不是真的做任何事情時,有一個獨特的約束呢。

+1

也許如果這是一種常見的查找,請更進一步。 https://gist.github.com/NotTheEconomist/0dc7ab0ee5270fc69cfa –

相關問題