SQLAlchemy:不能过滤混合属性

时间:2016-05-20 16:21:37

标签: python sqlalchemy

我有这张桌子:

class A(Base):
    __tablename__ = "A"

    child_id = Column(
        Integer, 
        ForeignKey("child.id"), 
        default = -1, 
        nullable = False, 
        primary_key = True
    )
    composite_id = Column(
        Integer, 
        ForeignKey("composite.id"), 
        default = -1, 
        nullable = False, 
        primary_key = True
    )
    composite = relationship("composite", uselist=False)

    @hybrid_property
    def child_ids(self):
        if self.child_id != -1:
            res = (self.child_id, )
        else:
            res = []

            for c in self.composite.childs:
                res.append(c.id)

        return tuple(res)

和这个composite表:

composite__child = Table(
    'composite__child', 
    Base.metadata,
    Column('composite_id', Integer, ForeignKey('composite.id')),
    Column('child_id', Integer, ForeignKey('child.id'))
)

composite_id_seq = Sequence('composite_id_seq')

class composite(Base):
    __tablename__ = "composite"

    id = Column(
        Integer, 
        server_default = composite_id_seq.next_value(), 
        nullable = False, 
        primary_key = True
    )
    name = Column(String(31), nullable=False)
    description = Column(String(255), nullable=False)
    childs = relationship("child", secondary=composite__child)

混合属性有效,但我无法对其进行过滤:

>>> db_con.query(A).all()[1].child_ids
(615,)
>>> db_con.query(A).filter_by(child_ids=(615),).all()
[]
>>> db_con.query(A).filter(A.child_ids==(615),).all()
[]

1 个答案:

答案 0 :(得分:0)

您需要将expression附加到混合动力才能执行任何过滤器。作为示例(由于您未包含compositechild的定义,可能无法直接使用):

class A(Base):
    ...

    @hybrid_property
    def child_ids(self):
        ...

    @child_ids.expression
    def child_ids(cls):
        return case([((cls.child_id != -1), array([cls.child_id]))],
                    else_=func.array_agg(child.__table__.select().where(child.composite_id == cls.composite_id)))