2015-06-03 15 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 –

相关问题