简体   繁体   English

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

[英]Using SQLAlchemy with composite primary and foreign keys

I am trying to create a relationship between two tables using declarative SQLAlchemy (v1.1.5) where the tables have composite primary and foreign keys.我正在尝试使用声明性 SQLAlchemy (v1.1.5) 在两个表之间创建关系,其中表具有复合主键和外键。

This is essentially a classic One-To-Many relationship between two tables, where Resource defines the parent, and each resource has multiple segments, defined in the Resourcesegment table.这本质上是两个表之间经典的一对多关系,其中 Resource 定义了父级,每个资源都有多个段,在 Resourcesegment 表中定义。 The twist is that I've added a VersionID column to both tables, so I can use the database with multiple versions of the data.不同之处在于,我已将 VersionID 列添加到两个表中,因此我可以将数据库与多个版本的数据一起使用。 Here's the simplified code:这是简化的代码:

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]),)

The error message I am getting is:我收到的错误消息是:

InvalidRequestError: Mapper 'Mapper|Resourcesegment|resourcesegment' has no property 'resource' InvalidRequestError: Mapper 'Mapper|Resourcesegment|resourcesegment' 没有属性 'resource'

I've tried many different configurations for relationships and foreign keys with no luck.我已经尝试了许多不同的关系和外键配置,但都没有成功。 From what I've understood in the documentation and various Stackoverflow examples, this is my best guess at what should work.根据我在文档和各种 Stackoverflow 示例中的理解,这是我对应该工作的最佳猜测。 Clearly I'm missing something.显然我错过了一些东西。

Thanks for any help / suggestions / comments!感谢您的任何帮助/建议/评论!

Assuming you're trying to use the segment PKs as FKs to Resource, try to define the FKs on the PK attribute definitions, eg along the lines of:假设您尝试使用段 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")

So I am answering my own question!所以我正在回答我自己的问题! It turns out that the original code I posted above is correct.事实证明,我上面发布的原始代码是正确的。 The problem I was experiencing was due to having a much more complicated set of tables in the actual model I am developing.我遇到的问题是由于我正在开发的实际模型中有一组更复杂的表。 One of the other tables had a problem, which ended up throwing an error making it look like the problem was with the above tables.其他表中的一个有问题,最终引发了一个错误,看起来问题出在上面的表上。 When I stripped everything away, as a result of creating this SO post, I got my simplified model to work, and was able to isolate the problem to another part of the bigger model.当我剥离所有东西时,由于创建了这个 SO 帖子,我让我的简化模型工作,并且能够将问题隔离到更大模型的另一部分。

One caveat: The error messages coming out of SQLAlchemy can be quite confusing, and not necessarily able to pinpoint the actual problem, without doing some extra debug work.一个警告:来自 SQLAlchemy 的错误消息可能非常令人困惑,并且不一定能够在不做一些额外的调试工作的情况下查明实际问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM