python sqlalchemy boolean

python - SQLAlchemy: resultados inesperados al usar `y` y` o`



boolean (1)

El problema es este:

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

Python no permite anular el comportamiento de las operaciones booleanas and y or . Puede influenciarlos hasta cierto punto con __bool__ en Python 3 y __nonzero__ en Python 2, pero todo lo que hace es que define el valor de verdad de su objeto .

Si los objetos en cuestión no hubieran implementado __bool__ y __bool__ arrojado el error, o la implementación no hubiera arrojado, posiblemente hubieras cometido errores crípticos debido a la naturaleza de cortocircuito de 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

porque

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

Esto podría y llevaría a que el cabello se arrastre en forma de expresiones SQL incorrectas:

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

Para producir expresiones SQL booleanas, use las and_() expresión and_() , or_() , y not_() sql, o el binario & , | , y ~ sobrecargas del operador:

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

o

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

o pasar múltiples criterios a una llamada a Query.filter() :

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

o combinar varias llamadas para filter() :

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

Tengo una base de datos "Noticias" creada a través de 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)

También tengo una función f(title) , que obtiene una cadena y devuelve una de las 3 variantes de cadenas: ''bueno'', ''quizás'' o ''nunca''. Intento obtener filas filtradas:

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

Pero el programa falla, provocando este error:

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

¿Cómo puedo resolverlo?