在声明性SQLAlchemy中创建容器关系

2024-04-19 02:32:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我的Python/SQLAlchemy应用程序管理一组节点,这些节点都是从基类Node派生的。使用alchemy的多态性来管理sqlm的多态性 SQLite3表中的节点。下面是base节点类的定义:

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:

^{pr2}$

现在我需要一种新的节点,ListNode,它是一个由零个或多个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)

孩子的名单应该只有 由节点对象组成——也就是说,我只需要它们的基类。在专业课中不应该完全实现 (除其他原因外,我不能一次得到整个图表)。

我从以下几行开始,把我在不同地方发现的零碎东西拼凑在一起,完全不了解 发生了什么,所以这可能没什么意义:

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”对象没有属性“\u sa_instance_state”。毫不奇怪,在这个主题上的几个小时的随机突变并没有给出任何结果 结果不错

我在sql炼金术方面的经验有限,但我真的很想让这个工作很快。如果您能给我任何建议或指导,我将不胜感激 提供。提前谢谢!


Tags: keytextidnodetrue节点titletype
1条回答
网友
1楼 · 发布于 2024-04-19 02:32:25

多对多关系需要一个附加表:

nodes_list_nodes = Table(
    'nodes_list_nodes', metadata,
    Column('parent_id', None, ForeignKey('nodes_list.id'), nullable=False),
    Column('child_id', None, ForeignKey(Node.id), nullable=False),
    PrimaryKeyConstraint('parent_id', 'child_id'),
)

class ListNode(Node):
    __mapper_args__ = {'polymorphic_identity': 'list'}
    __tablename__ = 'nodes_list'
    id = Column(None, ForeignKey('nodes.id'), primary_key=True)
    items = relation(Node, secondary=nodes_list_nodes)

更新:下面是使用association_proxy的有序列表示例:

^{pr2}$

相关问题 更多 >