我的模型中有一个自引用数据结构。它可以描述为
class Example(Base):
__tablename__ = 'example'
id = Column(Integer, primary_key=True)
title = Column(String(255))
parent_id = Column(Integer, ForeignKey('example.id'), nullable=True)
parent = relationship("Example")
我想在会话中创建一个包含一个或多个子节点的父节点。我的第一个方法是:
session.merge
)child.parent_id = parent.id
由于我希望将整个流程作为事务处理,因此我希望将其置于一个会话中。
我的问题,如果我使用一个会话:
设置child.parent = parent
会导致TypeError:ypeError: Incompatible collection type: None is not list-like
。设置child.parent_id = parent.id
不起作用,因为parent.id
尚未设置。
答案 0 :(得分:1)
这里的relationship()工作方向相反,代表一个子项列表,而不是父项列表。
它的工作原理如下:
class Example(Base):
__tablename__ = 'example'
id = Column(Integer, primary_key=True)
title = Column(String(255))
parent_id = Column(Integer, ForeignKey('example.id'), nullable=True)
children = relationship("Example")
然后您需要创建父记录并向其添加子记录:
sql = sqldb.get_session()
child1 = sqldb.system.Example()
child1.title = 'child-test'
sql.add(child1)
child2 = sqldb.system.Example()
child2.title = 'child-test2'
sql.add(child2)
parent = sqldb.system.Example()
parent.title = 'parent-test'
parent.children = [child1, child2]
sql.add(parent)
sql.commit()
答案 1 :(得分:-1)
class Example(Base):
__tablename__ = 'example'
id = Column(Integer, primary_key=True)
title = Column(String(255))
parent_id = Column(Integer, nullable=True)
尝试这样的事情,因为你只使用一张桌子,所以你不需要与自己建立关系。
你应该可以做类似
的事情ex1 = Example(1,'test')
session.add(ex1)
ex2 = Example(2,'test2',1)
# or ex2 = Example(2,'test2',ex1.id)
session.add(ex2)
应该有效
如果你坚持关于各种触发器的关系(我通常更愿意让程序员负责,而不是数据库的灵活性问题)使用remote_side
< / p>
class Example(Base):
__tablename__ = "example"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.Text, unique=True)
parent_id = db.Column(Integer,db.ForeignKey('example.id'))
children= relationship("Example",
backref=backref('parent', remote_side=[id])
)
这将创建邻接列表关系 有关详细信息,请参阅。
http://docs.sqlalchemy.org/en/improve_toc/orm/self_referential.html#adjacency-list-relationships