【问题标题】:sqlalchemy schema: there is no unique constraint matching given keys for referenced tablesqlalchemy 模式:没有唯一约束匹配引用表的给定键
【发布时间】:2014-10-29 22:29:34
【问题描述】:

我正在尝试使用结构相同但目的不同的 SQLAlchemy 模型创建 2 个表,WhitelistBlacklist 也引用了 Magazine(未显示)。它们都指向一个 Campaign 实例(比如一个政治运动),而该实例又具有一个指向 Politician 模型的 fkey(也未显示)。

我正在想象Whitelist/BlacklistCampaign 的数量:1,因为可能有多个白名单/黑名单,但在运行迁移时我得到sqlalchemy.exc.ProgrammingError: (ProgrammingError) there is no unique constraint matching given keys for referenced table "campaigns"。从CampaignPolitician 还需要有一个M:1。

有人可以解释为什么这会导致唯一约束错误,因为白名单和黑名单位于不同的表上?另外,我怎样才能使这个关系模式工作?

class Campaign(Base):
    __tablename__ = "campaigns"
    id = Column(Integer, primary_key=True, nullable=False)
    politician_id = Column(Integer, ForeignKey('politician.id'), nullable=False)
    description = Column(Text, nullable=True)


class Whitelist(Base):
    __tablename__ = "whitelist"
    id = Column(Integer, primary_key=True, nullable=False)
    campaign_id = Column(Integer, ForeignKey('campaign.id'), nullable=False)
    magazine_id = Column(Integer, ForeignKey('magazine.id'), nullable=False)


class Blacklist(Base):
    __tablename__ = "blacklist"
    id = Column(Integer, primary_key=True, nullable=False)
    campaign_id = Column(Integer, ForeignKey('campaign.id'), nullable=False)
    magazine_id = Column(Integer, ForeignKey('magazine.id'), nullable=False)

【问题讨论】:

    标签: python sql sqlalchemy database-schema alembic


    【解决方案1】:

    看起来这种关系确实是非法的,因为从Whitelist/BlacklistCampaign 的M:1,而Campaign 本身是一个M:1 到Politician。相反,我放弃了这种方法,模型现在看起来像:

    class Campaign(Base):
        __tablename__ = "campaigns"
        id = Column(Integer, primary_key=True, nullable=False)
        politician_id = Column(Integer, ForeignKey('politician.id'), nullable=False)
        description = Column(Text, nullable=True)
    
    
    class Listing(Base):
        __tablename__ = "listings"
        id = Column(Integer, primary_key=True, nullable=False)
        campaign_id = Column(Integer, ForeignKey('campaign.id'), nullable=False)
        magazine_id = Column(Integer, ForeignKey('magazine.id'), nullable=False)
        listing_type = Column(String, nullable=False)
    

    最初的方法旨在更好地适应Flask-Admin,但这种方法性能更高,因为它将减少前一个化身中所需的额外查询和连接。对于那些可能正在考虑将这种方法与Flask-Admin 一起使用的人,您可以使用inline_model() 来使用户界面更加简洁和易于管理。

    【讨论】:

    • 我不明白为什么表 A --> 表 B (M:1)、表 B --> 表 C (M:1) 是非法的。
    猜你喜欢
    • 2016-04-13
    • 2017-08-11
    • 1970-01-01
    • 2022-09-27
    • 2012-01-09
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多