В запросе SQLAlchemy будет использовать метод получения гибридного свойства без выделенного @...expression()
метода для создания необходимых объектов SQL, используемых для запроса.Метод получения привязан к классу , а не к экземпляру, поэтому self
в этом сценарии будет ссылаться на ваш Chap
класс.
Для вашего свойства cold_complain
это означает Chap.exclamation + ", it's cold!"
возвращается, в результате чего chap.exclamation || :exclamation_1
выражение SQL;+
переведен в оператор конкатенации SQL.
Но для вашего свойства hat_brag
возвращается строка;выполняемое выражение действительно "I have "+str(Chap.tophats)+" tophats!"
, которое становится 'I have Chap.tophats tophats!'
:
>>> "I have "+str(Chap.tophats)+" tophats!"
'I have Chap.tophats tophats!'
Это фиксированная статическая строка.Затем, это делается частью вашего фильтра, с == "I have 5 tophats!"
.Эти два статических строковых значения не равны:
>>> "I have "+str(Chap.tophats)+" tophats!" == "I have 5 tophats!"
False
Так вот, что используется в запросе SQL, отправляемом в базу данных.
Вместо этого вы хотите использоватьexpression()
option и определите SQL-версию вашего запроса:
from sqlalchemy.sql.expression import cast
class Chap(Base):
# ...
@hybrid_property
def hat_brag(self):
return "I have "+str(self.tophats)+" tophats!"
@hat_brag.expression
def hat_brag(cls):
return "I have " + cast(cls.tophats, String) + " tophats!"
Теперь метод expression
используется для запросов, а исходная функция для экземпляров - в Python.:
>>> c1.hat_brag
'I have 5 tophats!'
>>> print(Session().query(Chap).filter(Chap.hat_brag == "I have 5 tophats!"))
SELECT chap.id AS chap_id, chap.tophats AS chap_tophats, chap.exclamation AS chap_exclamation
FROM chap
WHERE :param_1 || CAST(chap.tophats AS VARCHAR) || :param_2 = :param_3