sqlalchemy架构:没有唯一约束匹配给定引用表的键

时间:2014-09-05 02:42:09

标签: python sql sqlalchemy database-schema alembic

我尝试使用结构相同但目的不同的SQLAlchemy模型创建2个表,WhitelistBlacklist也引用Magazine(未显示) )。他们都是一个竞选活动的实例(比如一个政治竞选活动),后者又有一个Politician模型的fkey(也未显示)。

我想象Whitelist / Blacklist为多个:1到Campaign因为可能有多个白名单/黑名单,但在运行迁移时我得到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)

1 个答案:

答案 0 :(得分:0)

由于从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()使UI更清晰,更易于管理。