2017-03-08 25 views
5

Tôi có một cơ sở dữ liệu "Tin tức" tạo ra thông qua SQLAlchemy:SQLAlchemy Boolean giá trị của khoản này không được định nghĩa

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) 

Tôi cũng có một hàm f (tiêu đề), mà được một chuỗi và trả về một trong 3 phiên bản của chuỗi: 'tốt', 'có thể' hoặc 'không bao giờ'. tôi cố gắng để có được hàng lọc:

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

Nhưng chương trình bị lỗi, nâng lỗi này:

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

Làm thế nào tôi có thể resovle nó?

+0

@ IljaEverilä Bạn nên đăng đó như là một câu trả lời, tôi gần như bỏ qua nhận xét của bạn và đã được viết cùng một điều. –

+0

Tôi đã cố gắng tìm một bản sao hiện có cho điều này, nhưng với một số bất ngờ có thể không. –

Trả lời

9

Vấn đề là thế này:

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

Python không cho phép trọng hành vi của boolean hoạt độngandor. Bạn có thể ảnh hưởng đến chúng ở một mức độ nào đó với __bool__ bằng Python 3 và __nonzero__ bằng Python 2, nhưng tất cả những gì có nghĩa là nó defines the truth value of your object.

Nếu các đối tượng trong câu hỏi đã không được thực hiện __bool__ và ném lỗi này, bạn sẽ đã nhận lỗi có thể là khá khó hiểu do sự 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 

thể này và sẽ dẫn đến việc kéo tóc dưới dạng các biểu thức SQL không chính xác:

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

Để tạo ra biểu thức SQL boolean thể sử dụng and_(), or_(), và not_() chức năng sql biểu hiện, hoặc nhị phân &, |, và ~ quá tải toán tử:

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

hoặc

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

hoặc vượt qua nhiều tiêu chí để gọi đến Query.filter():

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

hoặc kết hợp nhiều cuộc gọi đến filter():

filter(News.label == None).filter(f(News.title) == 'good') 
Các vấn đề liên quan