动态应用过滤器(自引用)关系

时间:2013-12-12 09:30:37

标签: python sqlalchemy

我有一个模型,我想用过滤器查询。我还希望将此过滤器应用于其子项(一对多自引用关系)。例如:

class Item(Model):
    __tablename__ = 'item'

    id = Column(Integer, primary_key=True)
    color = Column(String)

    parent_id = Column(Integer, ForeignKey('item.id'))
    children = relationship(
        'Item',
        backref=backref('parent', remote_side=[id]),
        lazy='dynamic'
    )

    item = session.query(Item).filter(Item.color == 'blue').one()

现在我想在children集合上应用相同的过滤器一次,并且以后可以透明地访问过滤后的集合。

我可以想象之类的东西:

item.children.apply_filter(Item.color == 'blue')  # `children` is dynamic

然后访问item.children就等同于现在访问item.children.filter(Item.color == 'blue').all()。请注意,使用此解决方案,关系是自引用的事实并不重要。

SQLAlchemy的API非常庞大,我无法弄清楚是否有正确的方法(或类似的东西)。

(是否可以在查询时修改关系的primaryjoin?或者给它一个参数?)

1 个答案:

答案 0 :(得分:0)

请注意,如果您有多个具有相同颜色的项目,则原始查询item = session.query(Item).filter(Item.color == 'blue').one()将失败。

当你越过那个并获得你的(父)Item实例时:

my_item = session.query(Item).filter(Item.color == 'blue')[0]
# my_item = session.query(Item).filter(Item.color == 'blue').filter(Item.parent == None).one() # assume this is only one root item per color

因为childrendynamicmy_item.children会返回一个查询。在这种情况下,您只需应用另一个过滤器即可完成:

my_blue_children = my_item.children.filter(Item.color == 'blue').all()

filter子句现在将过滤器应用于加载子项的select语句。