过滤器中的 SQLAlchemy 大小写表达式

问题描述 投票:0回答:1

有没有办法在 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]))
python sqlalchemy
1个回答
0
投票

如果没有最小的可重现示例,我实际上无法测试这是否有效,但我认为您正在寻找一个

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, )
    
© www.soinside.com 2019 - 2024. All rights reserved.