如何配置SQLAlchemy的ForeignKey级联删除,满足指定数据删除规则?
解决方案
要实现你的需求,只需要配置外键的ondelete参数,同时修正Event表的外键字段名(原来的user_id关联的是registration.id,语义明显不合理,建议改成registration_id),具体配置如下:
1. User与Registration的一对多关系
在Registration表的user_id外键中添加ondelete="CASCADE",这样删除User时,数据库会自动级联删除所有关联的Registration记录。
2. Registration与Event的一对一关系
把Event表的外键字段名修正为registration_id,然后给这个外键添加ondelete="SET NULL",同时设置该字段允许为空(nullable=True)。这样删除Registration时,Event的外键字段会被设为NULL,Event记录本身保留;删除User时,Registration被级联删除后,Event的外键也会自动设为NULL,Event依然保留。
修改后的完整模型代码
from sqlalchemy import Integer, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, Base, relationship class User(Base): __tablename__ = 'user' id: Mapped[int] = mapped_column( Integer, primary_key=True ) # 可选:添加关系属性,方便代码中关联查询 registrations: Mapped[list["Registration"]] = relationship(back_populates="user") class Registration(Base): __tablename__ = 'registration' id: Mapped[int] = mapped_column( Integer, primary_key=True ) user_id: Mapped[int] = mapped_column( ForeignKey('user.id', ondelete="CASCADE") ) # 可选:关联User的关系属性 user: Mapped["User"] = relationship(back_populates="registrations") # 可选:关联Event的一对一关系属性 event: Mapped["Event"] = relationship(back_populates="registration", uselist=False) class Event(Base): __tablename__ = 'event' id: Mapped[int] = mapped_column( Integer, primary_key=True ) registration_id: Mapped[int | None] = mapped_column( ForeignKey('registration.id', ondelete="SET NULL"), nullable=True ) # 可选:关联Registration的关系属性 registration: Mapped["Registration"] = relationship(back_populates="event")
参数说明
ondelete="CASCADE":父表(User)记录删除时,自动删除子表(Registration)中所有关联的记录,满足“删User同步删对应Registration”的要求。ondelete="SET NULL"+nullable=True:父表(Registration)记录删除时,子表(Event)的外键字段被设为NULL,Event记录本身保留,同时也适配了“删User后Event依然保留”的场景。
内容的提问来源于stack exchange,提问作者7 Reeds
相关产品推荐
相关产品推荐

