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

Posted

技术标签:

【中文标题】来自唯一和主外键的 SQLAlchemy 主键【英文标题】:SQLAlchemy Primary Key from Unique and Primary Foreign Keys 【发布时间】:2017-08-18 07:57:43 【问题描述】:

我有两个表格,报告和出价,具有一对多的关系,一个报告可以有多个出价。简化后的报告如下所示:

class Report(Base):
    __tablename__ = 'reports'
    
    dr_nbr = Column(CHAR(14), primary_key=True)
    header_trade = Column(VARCHAR(255), unique=True)
    bids = relationship("BidDetail", lazy="dynamic")

出价表如下所示:

class BidDetail(Base):
    __tablename__ = 'bids'
    
    report_id = Column(CHAR(14), primary_key=True)
    report_header_trade = Column(VARCHAR(255), primary_key=True)
    __table_args__ = (ForeignKeyConstraint(
                            [report_id, report_header_trade],
                            [Report.dr_nbr, Report.header_trade]),
                     )

我尝试了几种方法来从报告中导入这两个键并用作主键。我知道当我使用另一个表中的主外键时,我需要定义一个ForeignKeyConstraint,但是当一个外键是主外键而另一个外键是唯一时,它就不起作用了。我尝试过的另一件事(通过研究 SO 上的类似问题)是将作为外键的两个字段传递给 __table_args__UniqueConstraint,但我不确定我到底在做什么,它也没有工作。

如何在 SQLAlchemy 中导入两个外键,其中一个是 primary key,另一个是 unique 约束?

【问题讨论】:

问题是reports表中引用的列是单独唯一的。如果您在报告中添加了涵盖两列的唯一约束,您应该能够使用外键引用它们。请注意,如果您第一次尝试在没有它的情况下创建表,则数据库中可能有一个剩余的报告表。 我在进行更改之前删除了所有表,以确保这些表是全新创建的。您是否建议我在reports 表中创建一个UniqueConstraint 并将其传递给__table_args__?在这种情况下,我是保留还是删除 header_tradeunique 约束? 当报告中定义了唯一约束时,如何将这两列导入投标? __table_args__ = (UniqueConstraint(dr_nbr, header_trade), ) 将是一个解决方案。是否删除单个唯一约束取决于您所追求的。如果删除它,则可以有 (1, 1)、(2, 1)、(3, 1) 等对。另一方面,如果它们分别是唯一的并且作为一对是唯一的,则不能有重复的值。当唯一约束在报告中正确设置时,您当前的 BidDetail 实现应该按原样工作。 【参考方案1】:

感谢@ilja-everilä 帮助回答 cmets 中的问题。定义表的正确方法是:

class Report(Base):
    __tablename__ = 'reports'

    dr_nbr = Column(CHAR(14), primary_key=True)
    header_trade = Column(VARCHAR(255))
    __table_args__ = (UniqueConstraint(dr_nbr, header_trade),)
    contacts = relationship(
                    'Contact',
                    secondary='report_contact_link'
    )
    bids = relationship("BidDetail", lazy="dynamic")

class BidDetail(Base):
    __tablename__ = 'bids'

    report_id = Column(CHAR(14), primary_key=True)
    report_header_trade = Column(VARCHAR(255), primary_key=True)
    __table_args__ = (ForeignKeyConstraint(
                            [report_id, report_header_trade],
                            [Report.dr_nbr, Report.header_trade]),
                     )

【讨论】:

以上是关于来自唯一和主外键的 SQLAlchemy 主键的主要内容,如果未能解决你的问题,请参考以下文章

数据库主外键

数据库主外键

SQL中有主外键的两表到底那这是主表

主外键 子查询

超键(super key)、候选键(candidate key)和主键(primary key) 外键(foreign key)的区别

主键和外键的作用