2017-03-08 153 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')