代码之家  ›  专栏  ›  技术社区  ›  bc291

从sqlalchemy\u mptt Tree获取所有项目

  •  1
  • bc291  · 技术社区  · 8 年前

    我正在使用sqlalchemy创建树结构。我的模型定义如下:

    class TreeGroup(BaseNestedSets, db.Model):
        name = db.Column(db.String(400), index=True, unique=True)
        note = db.Column(db.Text(), nullable=True)
        items = db.relationship("Item", backref='item', lazy='dynamic')
    
        def __init__(self, name, parent_id=None):
            self.uuid = uuid4().hex
            self.name = name
            self.parent_id = parent_id
        def __repr__(self):
            return '{}'.format(self.name)
    
    class Item(db.Model):
        __tablename__ = 'items'
        id = db.Column(db.Integer, primary_key=True)
        category_id = db.Column(db.Integer, db.ForeignKey('tree_groups.id'))
        name = db.Column(db.String(475), index=True)
    

    插入的虚拟数据:

    db.session.add(TreeGroup(name="Root"))  # root node
        db.session.add_all(  # second level
        [
            TreeGroup(name="Test2", parent_id=1),  # id=2
            TreeGroup(name="Test3", parent_id=1),  # id=3
            TreeGroup(name="Test4", parent_id=1),  # id=4
        ]
        )
        db.session.add_all(  # third level
        [
            TreeGroup(name="Test5", parent_id=2),  # id=5
            TreeGroup(name="Test6", parent_id=2),  # id=6
            TreeGroup(name="Test7", parent_id=3),  # id=7
            TreeGroup(name="Test8", parent_id=3),  # id=8
            TreeGroup(name="Test9", parent_id=4),  # id=9
            TreeGroup(name="Test10", parent_id=4)  # id=10
        ]
        )
    
        db.session.add_all(  # fourth level
        [
            TreeGroup(name="Test11", parent_id=5),
            TreeGroup(name="Test12", parent_id=5),
            TreeGroup(name="Test13", parent_id=6),
            TreeGroup(name="Test14", parent_id=7)
        ]
        )
    
        db.session.commit()
    

    现在让我们关注id=3的节点(“Test3节点”)。我想查看它的所有项目,以及下面的项目。(来自子节点:Test7节点和Test8节点及其子节点(Test7)->Test14。

    我怎样才能做到这一点?我想: -递归的 -可能是一些复杂的sqlalchemy连接

    我也知道孩子可以通过以下途径获得:

    x = TreeGroup.query.filter_by(name=group_name).first()
    children = x.drilldown_tree() #but will that help me?
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Danila Ganchar    8 年前

    你说得对-你可以用 drilldown_tree() +递归。以下是示例:

    def print_tree(group_name, tab=1):
        """
        :param str group_name: 
        :param int tab: used just for formatting
        """
        group = TreeGroup.query.filter_by(name=group_name).one_or_none()  # type: TreeGroup
        if not group:
            return
        # group found - print name and find children 
        print('- ' * tab + group.name)
        for child_group in group.children:  # type: TreeGroup
            # new tabulation value for child record
            print_tree(child_group.name, tab * 2)
    

    示例:

    # print_tree('Test3')
    - Test3
    - - Test7
    - - - - Test14
    - - Test8
    # print_tree('Test2')
    - Test2
    - - Test5
    - - - - Test11
    - - - - Test12
    - - Test6
    - - - - Test13
    

    希望这有帮助。