0

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

我正在想象Whitelist/Blacklist是 many:1Campaign因为可能有多个白/黑名单,但是在运行迁移时我得到sqlalchemy.exc.ProgrammingError: (ProgrammingError) there is no unique constraint matching given keys for referenced table "campaigns". 还需要有一个 M:1 from Campaignto 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)
4

1 回答 1

0

看起来这种关系确实是非法的,因为Whitelist/Blacklist到的 M:1 Campaign,而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 更清洁且更易于管理。

于 2014-09-05T18:53:50.427 回答