有没有办法在 case 表达式上使用 in_ 运算符。 下面是一个人为的例子,但我想做这样的事情。
我可以定义一个hybrid_property以及一个表达式并且它可以工作,但是我可以在查询中动态地执行此操作吗?
# This does not work
class ReferralModel(Base):
id = Column(Integer, primary_key=True)
referrer_id = Column(Integer)
Session.query(ReferralModel.id).filter(case((ReferralModel.referrer_id.is_(None), -20), else_=ReferralModel.referrer_id).in_([-20, 10]))
推荐表
id | referrer_id |
---|---|
10 | 空 |
20 | 10 |
选择* 来自推荐 WHERE CASE WHEN Referrer_id IS NULL THEN -20 ELSE Referrer_id END IN (-20, 10)
# This works
class ReferralModel(Base):
id = Column(Integer, primary_key=True)
referrer_id = Column(Integer)
@hybrid_property
def referrer_id_no_nulls(self) -> int:
return self.referrer_id if not self.referrer_id else -20
@referrer_id_no_nulls.expression
def referrer_id_no_nulls_expression(cls):
return case((cls.referrer_id.is_(None), -20), else_=cls.referrer_id)
Session.query(ReferralModel.id).filter(ReferralModel.referrer_id_no_nulls_expression.in_([-20, 10]))
如果没有最小的可重现示例,我实际上无法测试这是否有效,但我认为您正在寻找一个
colmun_property
。
class ReferralModel(Base):
id = Column(Integer, primary_key=True)
referrer_id = Column(Integer)
referrer_id_no_nulls = column_property(
case((cls.referrer_id == None, -20), else_=cls.referrer_id),
)
我不知道在这种情况下是否需要自定义比较器,但由于我手头有示例,这是一个如何使用它的粗略示例。同样,这尚未经过测试,因此可能需要一些修复。
class CustomComparator(Comparator):
def __init__(self, column_property, mapper):
super().__init__(case((cls.referrer_id == None, -20), else_=cls.referrer_id))
self.cls = mapper.class_
def __eq__(self, value):
return or_(
self.cls.referrer_id == value,
and_(self.cls.referrer_id == None and value == -20),
)
def __ne__(self, value):
return and_(
self.cls.referrer_id != value,
or_(self.cls.referrer_id != None, value != -20),
)
class ReferralModel(Base):
id = Column(Integer, primary_key=True)
referrer_id = Column(Integer)
referrer_id_no_nulls = column_property(
case((cls.referrer_id == None, -20), else_=cls.referrer_id),
comparator_factory=CustomComparator,
)