sqlalchemy中复合外键的多个关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlalchemy中复合外键的多个关系相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个边类型类来链接两个节点。每个节点本身都是一个类,节点和边缘都应该是同一个图的一部分。我一直在

Could not determine join condition between parent/child tables on relationship TypeiNode.edges - there are no foreign keys linking these tables.

即使定义了外键。我尝试在节点表edges关系上定义外键,但得到了相同的结果。有人能告诉我这个例子有什么问题。

class Edge(Base):
    __tablename__ = 'edge'

    id = Column(Integer, primary_key=True)
    graph_id = Column(Integer, ForeignKey('graph.id'))
    graph= relationship('Graph', back_populates='graph_edges')
    type_1_node_id = Column(Integer, ForeignKey('type_1_node.id'))
    type_1_node = relationship('Type1Node',
                               back_populates='edges',
                               foreign_keys=[type_1_node_id, graph_id])
    type_2_node_id = Column(Integer, ForeignKey('type_2_node.id'))
    type_2_node = relationship('Type2Node',
                               back_populates='edges',
                               foreign_keys=[type_2_node_id, graph_id ])
    __table_args__ = (
        ForeignKeyConstraint(
            ['type_1_node_id', 'graph_id'],
            ['type_1_node.id','type_1_node.graph_id']),
        ForeignKeyConstraint(
            ['type_2_node_id', 'graph_id'],
            ['type_2_node.id','type_2_node.graph_id']),
    )    

class Type1Node(Base):
    __tablename__ = 'type_1_node'

    id = Column(Integer, primary_key=True)
    graph_id = Column(Integer, ForeignKey('graph.id'))
    graph = relationship('Graph', back_populates='graph_1_nodes')
    edges = relationship('Edge', back_populates='type_1_node')

class Type2Node(Base):
    __tablename__ = 'type_2_node'

    id = Column(Integer, primary_key=True)
    graph_id = Column(Integer, ForeignKey('graph.id'))
    graph = relationship('Graph', back_populates='graph_2_nodes')
    edges = relationship('Edge', back_populates='type_2_node')
答案

如果你仔细阅读错误,你会发现它并没有抱怨你添加了foreign_keys参数的关系,而是你没有注意到的关系:

Could not ... on relationship **TypeiNode.edges** ...

我拿

我尝试在节点表边缘关系上定义外键,但得到了相同的结果。

意思是你没有尝试同时定义两端。所以解决方案是在两端定义外键:

class Type1Node(Base):
    __tablename__ = 'type_1_node'

    id = Column(Integer, primary_key=True)
    graph_id = Column(Integer, ForeignKey('graph.id'))
    graph = relationship('Graph')
    edges = relationship('Edge', back_populates='type_1_node',
                         foreign_keys=[Edge.type_1_node_id, Edge.graph_id])

以上是关于sqlalchemy中复合外键的多个关系的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy外键的使用

SQLAlchemy ORM 不能使用复合外键

来自唯一和主外键的 SQLAlchemy 主键

SQLAlchemy(三):外键连表关系

主键和外键的复合键不能建立关系

SQLAlchemy 一个映射类中的多个外键到同一个主键