简体   繁体   English

SQLAlchemy - 在一对多关系中过滤子项

[英]SQLAlchemy - Filtering children in One-To-Many relationships

I have declared my models using the style described in the flask docs to have One-To-many relationships. 我使用flask文档中描述的样式声明我的模型具有一对多关系。 The models are nested twice - I have Articles with Segments with Items. 这些模型嵌套了两次 - 我有条款与项目的文章。

Both Segments and Items have a visibility attribute which can be True or False. Segments和Items都有一个可见性属性,可以是True或False。 When editing, I just select all items, but when displaying I'd like to only select those which the visibility attribute is True . 编辑时,我只选择所有项目,但在显示时我只想选择能见度属性为True那些项目。

Is there an idiom in SQLAlchemy for filtering children? SQLAlchemy中是否有用于过滤子项的习惯用法? I've tried with subqueries but could not achieve what I wanted. 我尝试过子查询但无法达到我想要的效果。

Eg. 例如。 I want to achieve: 我想实现:

A single article -> Visible Segment 1 -> This segment's Visible Item 1
                                      -> This segment's Visible Item 2
                 -> Visible Segment 2 -> This segment's Visible Item 1
                                      -> This segment's Visible Item 2

if the relationships refer to small numbers of objects I typically just do this in Python: 如果关系引用少量对象,我通常只在Python中执行此操作:

class Article(Base):
    # ...

    segments = relationship(Segment)

    @property
    def visible_items(self):
        return [item for segment in self.segments 
                     for item in segment.items
                     if segment.visible and item.visible]

class Segment(Base):
    # ...

    items = relationship(Item)

now if you really want to go full relationship for this, you can define an alternate relationship with that primaryjoin: 现在如果你真的想要为此建立完整的关系,你可以定义与该主连接的替代关系:

class Article(Base):
    # ...

    segments = relationship(Segment)

    visible_segments = relationship(Segment, 
            primaryjoin="and_(Segment.article_id == Article.id, Segment.visible == True)")

    @property
    def visible_items(self):
        return [item for segment in self.visible_segments 
                     for item in segment.visible_items]

class Segment(Base):
    # ...

    items = relationship(Item)
    visible_items = relationship(Item, 
               primaryjoin="and_(Item.segment_id == Segment.id, Item.visible==True)")

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

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