将SQLAlchemy与复合主键和外键一起使用

时间:2017-03-27 15:53:57

标签: python sqlalchemy foreign-keys relationship foreign-key-relationship

我正在尝试使用声明性SQLAlchemy(v1.1.5)在两个表之间创建关系,其中表具有复合主键和外键。

这实际上是两个表之间的经典一对多关系,其中Resource定义父级,每个资源都有多个段,在Resourcesegment表中定义。扭曲的是我已经向两个表添加了一个VersionID列,因此我可以将数据库与多个版本的数据一起使用。这是简化的代码:

from sqlalchemy import Column, String, Integer, ForeignKeyConstraint
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()

class Resource(Base):
    __tablename__ = 'resource'
    VersionID = Column(String, primary_key=True)
    ResourceID = Column(String, primary_key=True)
    ResourceProperty = Column(String)
    segments = relationship("Resourcesegment", back_populates="resource")

class Resourcesegment(Base):
    __tablename__ = 'resourcesegment'
    VersionID = Column(String, primary_key=True)
    ResourceID = Column(String, primary_key=True)
    Segment_Type = Column(String, primary_key=True)
    Segment_Number = Column(Integer, primary_key=True)
    Segment_Property = Column(String)
    resource = relationship("Resource", foreign_keys=[VersionID, ResourceID], back_populates="segments")

    __table_args__ = (ForeignKeyConstraint([VersionID, ResourceID], [Resource.VersionID, Resource.ResourceID]),)

我收到的错误消息是:

  

InvalidRequestError:Mapper' Mapper | Resourcesegment | resourcesegment'没有财产资源'

我为关系和外键尝试了许多不同的配置而没有运气。根据我在文档和各种Stackoverflow示例中所理解的内容,这是我对应该工作的最佳猜测。显然,我错过了一些东西。

感谢您提供任何帮助/建议/意见!

2 个答案:

答案 0 :(得分:0)

假设您尝试将段PK用作资源的FK,请尝试在PK属性定义上定义FK,例如沿着这条线:

class Resourcesegment(Base):
    __tablename__ = 'resourcesegment'
    VersionID = Column(String, ForeignKey(Resource.VersionID), primary_key=True)
    ResourceID = Column(String, ForeignKey(Resource.ResourceID), primary_key=True)
    Segment_Type = Column(String, primary_key=True)
    Segment_Number = Column(Integer, primary_key=True)
    Segment_Property = Column(String)
    resource = relationship("Resource", back_populates="segments")

答案 1 :(得分:0)

所以我回答了我自己的问题!事实证明我上面发布的原始代码是正确的。我遇到的问题是由于我正在开发的实际模型中有一组更复杂的表。其中一个表有一个问题,最终抛出错误使它看起来像上面的表的问题。当我删除所有内容时,由于创建了这个SO帖子,我让我的简化模型工作,并且能够将问题隔离到更大模型的另一部分。

一个警告:来自SQLAlchemy的错误消息可能非常混乱,并且不一定能够查明实际问题,而无需进行额外的调试工作。