【问题标题】:Multiple relationships on composite foreign keys in sqlalchemysqlalchemy中复合外键的多重关系
【发布时间】:2018-05-30 23:19:43
【问题描述】:

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

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')

【问题讨论】:

    标签: python orm sqlalchemy relationship


    【解决方案1】:

    如果您仔细阅读该错误,您会发现它并没有抱怨您添加了 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])
    

    【讨论】:

    • 感谢@Ilja Everilä,这行得通。但是,我确实收到了形式为 SAWarning: relationship Edge.type_1_node' will copy column type_1_node.graph_id to column edge.graph_id, which conflicts with relationship(s): 'Edge.graph' (copies graph.id to edge.graph_id). Consider applying viewonly=True to read-only relationships, or provide a primaryjoin condition marking writable columns with the foreign() annotation. 的警告。有没有更好的方法来构建这个 Node-Edge-Graph 关系方案?
    猜你喜欢
    • 2020-05-30
    • 2013-02-21
    • 2020-12-30
    • 2011-11-22
    • 2016-09-06
    • 1970-01-01
    • 2015-10-21
    • 2017-05-24
    相关资源
    最近更新 更多