我设置了一个映射...
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上查询他,该属性包含一个int
转换为str
...
>>>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
错误的地方。那看起来不像是正确的查询!有人知道怎么回事吗?
答案 0 :(得分:1)
在查询中,SQLAlchemy将使用混合属性的getter方法(不带专用的@...expression()
method)来生成用于查询的必要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