我设置了一个映射...
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from sqlalchemy.ext.hybrid import hybrid_property
Base = declarative_base()
class Chap(Base):
__tablename__ = 'chap'
id = Column(Integer, primary_key=True)
tophats = Column(Integer)
exclamation = Column(String)
@hybrid_property
def hat_brag(self):
return "I have "+str(self.tophats)+" tophats!"
@hybrid_property
def cold_complain(self):
return self.exclamation+", it's cold!"
...我创造了一个小伙子。
>>>c1 = Chap(tophats=5, exclamation="Blimey")
现在我想根据他提示天气的方式来查询这个人:
>>>print(Session().query(Chap).filter(Chap.cold_complain == "Blimey, it's cold!"))
SELECT chap.id AS chap_id, chap.tophats AS chap_tophats, chap.gloves AS chap_gloves, chap.exclamation AS chap_exclamation
FROM chap
WHERE chap.exclamation || :exclamation_1 = :param_1
那个 SQL 代码看起来是正确的,但现在我想在另一个 hybrid_property 上查询他,一个包含转换为 str
的 int
...
>>>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 false
哪里是假的。这看起来不像是正确的查询!有人知道这是怎么回事吗?
最佳答案
在查询中,SQLAlchemy 将使用没有专用 @...expression()
method 的混合属性的 getter 方法生成用于查询的必要 SQL 对象。 getter 方法绑定(bind)到类,而不是实例,所以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
关于python - 混合属性的过滤器计算结果为 "where false",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54487741/