sqlalchemy 模式:引用表没有匹配给定键的唯一约束
我正在尝试使用SQLAlchemy模型创建两个结构相同但目的不同的表,分别是Whitelist
(白名单)和Blacklist
(黑名单),这两个表都与一个Magazine
(杂志)相关联(杂志的内容这里不展示)。它们都通过外键(fkey)连接到一个Campaign
(活动)实例,比如说一个政治活动,而这个活动又有一个外键指向Politician
(政治人物)模型(同样不展示)。
我想象中的Whitelist
和Blacklist
与Campaign
之间是多对一的关系,因为可能会有多个白名单和黑名单对应同一个活动。但是在运行迁移时,我遇到了一个错误:sqlalchemy.exc.ProgrammingError: (ProgrammingError) there is no unique constraint matching given keys for referenced table "campaigns"
。此外,Campaign
和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 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
看起来这个关系确实不合法,因为从 Whitelist
/Blacklist
到 Campaign
是一种多对一的关系,而 Campaign
本身又是多对一地指向 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()
来让界面看起来更整洁,更容易管理。