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

मैं भी एक समारोह च (शीर्षक) है, कि एक स्ट्रिंग हो जाता है और 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 

अजगर बूलियन संचालनand और or के व्यवहार अधिभावी अनुमति नहीं है। आप पाइथन 3 और __nonzero__ में पाइथन 2 में के साथ कुछ हद तक उन्हें प्रभावित कर सकते हैं, लेकिन यह सब है कि यह 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 

यह कर सकता है और गलत एसक्यूएल एक्सप्रेशन के रूप में खींचने वाले बाल का नेतृत्व करेंगे:

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

बूलियन एसक्यूएल भाव उत्पादन या तो and_(), or_(), और not_() एसक्यूएल अभिव्यक्ति काम करता है, या बाइनरी &, |, और ~ ऑपरेटर भार के उपयोग करने के लिए:

# 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') 
संबंधित मुद्दे