繁体   English   中英

在SQLAlchemy中按对象过滤

[英]Filter by an object in SQLAlchemy

我有一个声明的模型,表中存储了一个对象的“原始”路径标识符。 然后我有一个@hybrid_property ,它允许直接获取和设置由该字段标识的对象(这不是另一个声明性模型)。 有没有办法直接在这个高级别查询?

我可以做这个:

session.query(Member).filter_by(program_raw=my_program.raw)

我希望能够这样做:

session.query(Member).filter_by(program=my_program)

其中my_program.raw == "path/to/a/program"

Member有一个字段program_raw和一个属性program ,它获取正确的Program实例并设置适当的program_raw值。 Program有一个简单的raw字段,可以唯一标识它。 如有必要,我可以提供更多代码。

问题是,目前,SQLAlchemy只是尝试将程序实例作为参数传递给查询,而不是raw值。 这会导致Error binding parameter 0 - probably unsupported type. 错误。

  • 或者,SQLAlchemy需要知道,在比较program ,它必须使用Member.program_raw并将其与参数的raw属性进行匹配。 让它使用Member.program_raw只是使用@program.expression但我无法弄清楚如何正确翻译Program参数(使用Comparator?),和/或
  • SQLAlchemy应该知道,当我按Program实例过滤时,它应该使用raw属性。

我的用例可能有点抽象,但想象一下,我在数据库中存储了一个序列化的RGB值,并在模型上有一个带有Color类的属性。 我想通过Color类进行过滤,而不必处理我的过滤器中的RGB值。 颜色类没有问题告诉我它的RGB值。

通过阅读relationship来源找出它。 诀窍是为属性使用自定义Comparator ,它知道如何比较两件事。 就我而言,它很简单:

from sqlalchemy.ext.hybrid import Comparator, hybrid_property

class ProgramComparator(Comparator):
    def __eq__(self, other):
        # Should check for case of `other is None`
        return self.__clause_element__() == other.raw

class Member(Base):
    # ...
    program_raw = Column(String(80), index=True)

    @hybrid_property
    def program(self):
        return Program(self.program_raw)

    @program.comparator
    def program(cls):
        # program_raw becomes __clause_element__ in the Comparator.
        return ProgramComparator(cls.program_raw)

    @program.setter
    def program(self, value):
        self.program_raw = value.raw

注意:在我的情况下, Program('abc') == Program('abc') (我已经覆盖__new__ ),所以我可以一直返回一个“新”程序。 对于其他情况,实例应该可以延迟创建并存储在Member实例中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM