从 dictionary/JSON 构建层次结构
Constructing hierarchy from dictionary/JSON
我正在寻找一种在两个或多个相同 class 实例之间以子父关系形式创建层次结构的方法。
如何像示例中那样从嵌套字典创建此类对象?这可能吗?有没有其他推荐的方法来完成这样的任务?
# -*- 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()
我理解迭代方法,我首先创建父对象,然后遍历可能的子对象并创建它们。我很好奇是否有一种方法可以在构造函数内部执行此操作,而不是从 'outside' 循环执行此操作。
试试这个。
#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')
,并且 运行 它多次执行,它会在一次添加和提交时创建所有条目。
不同的方法
您也可以创建一个单独的“团队”table 来存储团队负责人和团队成员
# 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
我正在寻找一种在两个或多个相同 class 实例之间以子父关系形式创建层次结构的方法。
如何像示例中那样从嵌套字典创建此类对象?这可能吗?有没有其他推荐的方法来完成这样的任务?
# -*- 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()
我理解迭代方法,我首先创建父对象,然后遍历可能的子对象并创建它们。我很好奇是否有一种方法可以在构造函数内部执行此操作,而不是从 'outside' 循环执行此操作。
试试这个。
#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')
,并且 运行 它多次执行,它会在一次添加和提交时创建所有条目。
不同的方法
您也可以创建一个单独的“团队”table 来存储团队负责人和团队成员
# 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