2017-03-08 148 views
5

我有一个数据库,“新闻”通过SQLAlchemy的创建:SQLAlchemy的布尔值没有定义

class News(Base): 
    __tablename__ = "news" 
    id = Column(Integer, primary_key = True) 
    title = Column(String) 
    author = Column(String) 
    url = Column(String) 
    comments = Column(Integer) 
    points = Column(Integer) 
    label = Column(String) 

我也有一个函数f(职称),即获得一个字符串并返回的3个变种一个字符串:“好”,“可能”或“从不”。 我试图让过滤行:

rows = s.query(News).filter(News.label == None and f(News.title)=='good').all() 

但是程序失败,提出这个错误:

raise TypeError("Boolean value of this clause is not defined") 

我怎么能resovle呢?

+0

@IljaEverilä你应该张贴,作为一个答案,我几乎错过您的评论,并已写同样的事情。 –

+0

我试图找到一个现有的重复,但有些惊喜不能。 –

回答

9

问题是这样的:

News.label == None and f(News.title) == 'good' 
#     ^^^ here 

的Python不允许覆盖布尔操作andor的行为。 Python 2中的__bool__和Python 2中的__nonzero__可以在某种程度上影响它们,但它所做的只是它defines the truth value of your object

如果有问题的对象没有执行__bool__和抛出的错误,你就已经得到了可能是非常模糊的错误是由于short-circuiting nature of and and or

In [19]: (News.label == 'asdf') and True 
Out[19]: <sqlalchemy.sql.elements.BinaryExpression object at 0x7f62c416fa58> 

In [24]: (News.label == 'asdf') or True 
Out[24]: True 

因为

In [26]: bool(News.label == 'asdf') 
Out[26]: False 

这可能和会导致以不正确的SQL表达式形式拉毛:

In [28]: print(News.label == 'asdf' or News.author == 'NOT WHAT YOU EXPECTED') 
news.author = :author_1 

为了产生布尔SQL表达式要么使用and_()or_(),和not_() SQL表达的功能,或二进制&|,和~运算符重载:

# Parentheses required due to operator precedence 
filter((News.label == None) & (f(News.title) == 'good')) 

filter(and_(News.label == None, f(News.title) == 'good')) 

或传递多个准则致电Query.filter()

filter(News.label == None, f(News.title) == 'good') 

,或者把多个呼叫filter()

filter(News.label == None).filter(f(News.title) == 'good')