在 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_id 和 client_id 集,
示例: 我删除了 VolunteerClient table 其中:volunteer_id = 1, & client_id = 1,
我想要删除所有 VolunteerReports,其中:volunteer_id = 1,& client_id = 1。我是否使用 FK 引用 volunteer_client 和 cascade='all, delete'
?
正确设置了它
任何建议都很棒。
要在删除父行时自动删除子行,您需要在子行 table 中定义的外键上设置 ondelete='CASCADE'
。在这种情况下,外键是一个 复合 键,因为它由 volunteer_id
和 client_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,这样您就可以更好地控制删除父行时发生的情况。由于您似乎没有使用关系,并且数据库级联会执行您想要的操作,因此我不会在这个答案中介绍它。
我有一个 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_id 和 client_id 集,
示例: 我删除了 VolunteerClient table 其中:volunteer_id = 1, & client_id = 1,
我想要删除所有 VolunteerReports,其中:volunteer_id = 1,& client_id = 1。我是否使用 FK 引用 volunteer_client 和 cascade='all, delete'
?
任何建议都很棒。
要在删除父行时自动删除子行,您需要在子行 table 中定义的外键上设置 ondelete='CASCADE'
。在这种情况下,外键是一个 复合 键,因为它由 volunteer_id
和 client_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,这样您就可以更好地控制删除父行时发生的情况。由于您似乎没有使用关系,并且数据库级联会执行您想要的操作,因此我不会在这个答案中介绍它。