在 FLASK SQLAlchemy 中删除一个特定的 table 时删除许多 table

Deleting many tables when one specific table is deleted in FLASK SQLAlchemy

我有一个 SQLAlchemy VolunteerClient 模型,它是一个 join table:

class VolunteerClient(Base):
    __tablename__ = 'volunteer_client'

    id = Column(Integer, primary_key=True, autoincrement=True, index=True)
    volunteer_id = Column(Integer, ForeignKey('provider_user.user_id', onupdate='CASCADE', ondelete='RESTRICT'), unique=True)
    client_id = Column(Integer, ForeignKey('user.id', onupdate='CASCADE', ondelete='RESTRICT'), unique=True)

和一个 VolunteerReport 模型:

class VolunteerReport(Base):
    __tablename__ = 'volunteer_report'

    id = Column(Integer, primary_key=True, autoincrement=True, index=True)
    volunteer_id = Column(Integer, ForeignKey('volunteer_client.volunteer_id', cascade="all, delete"))
    client_id = Column(Integer, ForeignKey('volunteer_client.client_id', cascade="all, delete"))
    report = Column(String(255), nullable=False)
    report_category = Column(String(255), nullable=False)

如果我要删除 VolunteerClient table,这实际上是从客户端取消分配志愿者,但实际上并没有删除 users 他们所代表的。具有特定的 volunteer_idclient_id 集,

示例: 我删除了 VolunteerClient table 其中:volunteer_id = 1, & client_id = 1,

我想要删除所有 VolunteerReports,其中:volunteer_id = 1,& client_id = 1。我是否使用 FK 引用 volunteer_clientcascade='all, delete'?

正确设置了它

任何建议都很棒。

要在删除父行时自动删除子行,您需要在子行 table 中定义的外键上设置 ondelete='CASCADE'。在这种情况下,外键是一个 复合 键,因为它由 volunteer_idclient_id 组成。这意味着您还需要对父级中的列进行唯一约束。您的模型的这个简化版本显示了它是如何工作的(我已经从 VolunteerClient 中删除了 FK 定义,问题中定义了 table)。

class VolunteerClient(Base):
    __tablename__ = 'volunteer_client'

    id = sa.Column(sa.Integer, primary_key=True)
    volunteer_id = sa.Column(sa.Integer)
    client_id = sa.Column(sa.Integer)

    __table_args__ = (sa.UniqueConstraint(volunteer_id, client_id),)


class VolunteerReport(Base):
    __tablename__ = 'volunteer_report'

    id = sa.Column(sa.Integer, primary_key=True)
    volunteer_id = sa.Column(sa.Integer)
    client_id = sa.Column(sa.Integer)

    __table_args__ = (
        sa.ForeignKeyConstraint(
            [volunteer_id, client_id],
            [VolunteerClient.volunteer_id, VolunteerClient.client_id],
            ondelete='CASCADE',
        ),
    )

您还可以配置 delete cascades on SQLAlchemy relationships,这样您就可以更好地控制删除父行时发生的情况。由于您似乎没有使用关系,并且数据库级联会执行您想要的操作,因此我不会在这个答案中介绍它。