从字典/JSON 构建层次结构 [英] Constructing hierarchy from dictionary/JSON

查看:70
本文介绍了从字典/JSON 构建层次结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种在同一类的两个或多个实例之间以子父关系形式创建层次结构的方法.

I'm looking for a way to create hierarchy in form of child parent relationship between two or more instances of same class.

如何像示例中那样从嵌套字典中创建这样的对象?这甚至可能吗?有没有其他方法可以推荐来做这样的任务?

How would one go about creating such objects from nested dictionary like in example ? Is this even possible ? Is there some other way which would be recommended to do such task?

# -*- coding: utf-8 -*-

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, exists
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.types import Integer, String

Base = declarative_base()

class Person(Base):
    __tablename__ = 'person';
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    parent_id = Column(Integer, ForeignKey('person.id'))

    def __init__(self, **kwargs):
        self.parent_id = kwargs.get('parent_id', None)
        self.name = kwargs.get('name')
        self.team = kwargs.get('team', [])
        # Is it possible to create more object of this type
        # and establish that their parent_id is ID of this object?


    def __repr__(self):
        return """
        ID: {}
        Name: {}
        ParentID: {}
                """.format(self.id, self.name, self.parent_id)


engine = create_engine('sqlite:///db.sqlite3')
Base.metadata.create_all(engine)
connection = engine.connect()
Session = sessionmaker(bind=engine)
session = Session()

alice = {'name' : 'Alice'}
bob = {'name' : 'Bob', 'team' : [alice, ]}

p1 = Person(bob)
session.add(p1)
session.commit()

我理解迭代方法,我首先创建父对象,然后迭代可能的子对象并创建它们.我很好奇是否有办法在构造函数内部而不是从外部"使用循环来做到这一点.

I understand the iterative approach where I would first create parent object, then iterate over possible children and create them. I'm curious if there is a way to do this inside constructor rather than from 'outside' with loops.

推荐答案

试试这个.

#your import statements including "relationship"

Base = declarative_base()


class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    parent_id = Column(Integer, ForeignKey('person.id'))

    team = relationship("Person")  

    def __init__(self, **kwargs):
        self.parent_id = kwargs.get('parent_id', None)
        self.name = kwargs.get('name')
        team_kwargs = kwargs.get('team', [])
        for member_kwargs in team_kwargs:
            new_person = Person(**member_kwargs)
            new_person.parent_id = self.id
            self.team.append(new_person)
        # Is it possible to create more object of this type
        # and establish that their parent_id is ID of this object?
    
    def __repr__(self):
        return """
        ID: {}
        Name: {}
        ParentID: {}
                """.format(self.id, self.name, self.parent_id)


engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
connection = engine.connect()
Session = sessionmaker(bind=engine)
session = Session()



alice = {'name' : 'Alice'}
joe = {'name' : 'Joe'}
anne = {'name' : 'Anne', 'team': [alice]}
bob = {'name' : 'Bob', 'team' : [anne, joe]}

p1 = Person(**bob) 

session.add(p1)   
session.commit()

for person in session.query(Person).all():
    print(person)

输出:

    ID: 1
    Name: Bob
    ParentID: None
            

    ID: 2
    Name: Anne
    ParentID: 1
            

    ID: 3
    Name: Joe
    ParentID: 1
            

    ID: 4
    Name: Alice
    ParentID: 2

当我在保存的数据库上运行它时,(engine = create_engine('sqlite:///delme.db'),并多次运行它,它在单个数据库上创建了所有条目添加并提交.

when i ran this on a saved database, (engine = create_engine('sqlite:///delme.db'), and ran it multiple times, it created all the entries on a single add and commit.

您也可以创建一个单独的团队"存储团队领导和团队成员的表格

You could also make a separate "teams" table that stores team leader and team members

# your imports and "from sqlalchemy import create_engine, Table"

Base = declarative_base()

teams = Table("teams", Base.metadata,
              Column("leader", Integer, ForeignKey("person.id"), primary_key=True),
              Column("member", Integer, ForeignKey("person.id"), primary_key=True),
              )


class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    team = relationship("Person",
                        secondary=teams,
                        primaryjoin=id==teams.c.leader,
                        secondaryjoin=id==teams.c.member,
                        )

    def __init__(self, **kwargs):
        self.name = kwargs.get('name')
        team_input = kwargs.get('team', [])
        for member in team_input:
            new_person = Person(**member)
            self.team.append(new_person)

        def __repr__(self):
    return "ID: {}  Name: {}".format(self.id, self.name)

engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
connection = engine.connect()
Session = sessionmaker(bind=engine)
session = Session()

alice = {'name' : 'Alice'}
joe = {'name' : 'Joe'}
anne = {'name' : 'Anne', 'team': [alice]}
bob = {'name' : 'Bob', 'team' : [anne, joe]}

p1 = Person(**bob)
session.add(p1)
session.commit()

for person in session.query(Person).all():
    print(person)


for team in session.query(teams).all():
    print(team)

输出:

ID: 1  Name: Bob
ID: 2  Name: Anne
ID: 3  Name: Alice
ID: 4  Name: Joe
(1, 2)  # anne and joe are on bob's team
(1, 4)
(2, 3)  # alice is on anne's team

这篇关于从字典/JSON 构建层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆