我的Python/SQLAlchemy应用程序管理一组节点,这些节点都是从一个基类Node派生而来。我正在使用SQLAlchemy的多态特性来在SQLite3表中管理这些节点。以下是基本Node类的定义:
class Node(db.Base):
__tablename__ = 'nodes'
id = Column(Integer, primary_key=True)
node_type = Column(String(40))
title = Column(UnicodeText)
__mapper_args__ = {'polymorphic_on': node_type}
例如,其中一个派生类NoteNode:
class NoteNode(Node):
__mapper_args__ = {'polymorphic_identity': 'note'}
__tablename__ = 'nodes_note'
id = Column(None,ForeignKey('nodes.id'),primary_key=True)
content_type = Column(String)
content = Column(UnicodeText)
现在我需要一个新的节点类型,ListNode,它是零个或多个Node的有序容器。 当我加载一个ListNode时,我希望它具有其ID和标题(来自基类Node)以及其包含的(子)节点集合。 一个Node可能出现在多个ListNode中,因此它不是一个适当的层次结构。 我会按照以下方式创建它们:
note1 = NoteNode(title=u"Note 1", content_type="text/text", content=u"I am note #1")
session.add(note1)
note2 = NoteNode(title=u"Note 2", content_type="text/text", content=u"I am note #2")
session.add(note2)
list1 = ListNode(title=u"My List")
list1.items = [note1,note2]
session.add(list1)
子节点列表应该只包含Node对象 - 也就是说,我只需要它们的基类内容。它们不应该完全实现为专门的类(因此我不能一次获取整个图形,还有其他原因)。
我开始按照以下方式进行,拼凑了我在各种地方找到的碎片,但并没有完全理解正在发生什么,所以这可能没有太多意义:
class ListNode(Node):
__mapper_args__ = {'polymorphic_identity': 'list', 'inherit_condition':id==Node.id}
__tablename__ = 'nodes_list_contents'
id = Column(None, ForeignKey('nodes.id'), primary_key=True)
item_id = Column(None, ForeignKey('nodes.id'), primary_key=True)
items = relation(Node, primaryjoin="Node.id==ListNode.item_id")
这种方法有几个问题:似乎不允许空的ListNode,而将items属性设置为列表会导致SQLAlchemy抱怨'list'对象没有'_sa_instance_state'属性。毫不奇怪,对这个主题进行数小时的随机变异也没有给出任何好的结果。
我在SQLAlchemy方面经验有限,但真的希望尽快使其正常工作。非常感谢您能提供任何建议或指导。提前致谢!
class ListNodeAssociation(Base): __tablename__ = 'nodes_list_nodes' parent_id = Column(None, ForeignKey('nodes_list.id'),primary_key=True) child_id = Column(None, ForeignKey(Node.id),primary_key=True)
我仍然需要按顺序排列关系,最好通过SQLAlchemy的“orderinglist”机制实现,但我不清楚它在这种情况下如何应用...它是否适用,如果是,如何使用? - jgarbers