删除Parent对象触发sqlalchemy.exc.IntegrityError的原因排查
为什么删除Parent对象时会触发IntegrityError?
先来看你的模型代码,方便我们定位问题:
class Parent(): id = Column(Integer ,primary_key = true) children = relationship('Child', back_populates='parent', passive_deletes =True) dependents = relationship('Dependent', back_populates='parent', passive_deletes =True) class Child(): id = Column(Integer , primary_key = true) parent = relationship('Parent', back_populates='children') parent_id = Column(Integer, ForeignKey('parent.id', ondelete='CASCADE')) anothers = relationship('Another', back_populates='child') class Dependent(): id = Column(Integer , primary_key = true) parent = relationship('Parent', back_populates='children') parent_id = Column(Integer, ForeignKey('parent.id', ondelete='CASCADE')) another = relationship('Another', back_populates='dependent', uselist=False, passive_deletes = True) class Another(): id = Column(Integer , primary_key = true) dependent = relationship('Dependent', back_populates='anothers') dependent_id = Column(Integer, ForeignKey('dependent.id', ondelete='CASCADE')) child = relationship('Child', back_populates='another') child_id = Column(Integer, ForeignKey('child.id'))
问题根源:数据库级联删除时的外键约束缺失
咱们一步步捋清楚删除Parent时发生的事情:
- 因为你给Parent和Child的关系设置了
passive_deletes=True,同时Child的parent_id外键带了ondelete='CASCADE',所以删除Parent时,数据库会直接发起级联删除,把所有关联的Child记录删掉——这一步SQLAlchemy不会主动干预处理Child关联的其他对象。 - 但Another表的
child_id外键只写了ForeignKey('child.id'),没有添加任何ondelete约束(比如置空或者级联删除)。这就导致数据库删除Child记录时,Another表中还有引用这个Child ID的记录,直接触发了外键约束违反的错误。
那为什么单独删Child时没问题呢?因为这时候SQLAlchemy会主动介入:通过Child.anothers这个关系找到所有关联的Another记录,把它们的child_id设为null(这是relationship的默认行为,只要外键允许为null),之后再删除Child,所以数据库层面不会报错。
修复方案
你只需要修改Another表的child_id外键定义,加上符合你预期的ondelete约束就行:
- 如果希望删除Child时,Another的
child_id自动置空(和单独删Child的行为一致):child_id = Column(Integer, ForeignKey('child.id', ondelete='SET NULL')) - 如果希望删除Child时,关联的Another记录也跟着被删:
child_id = Column(Integer, ForeignKey('child.id', ondelete='CASCADE'))
这样再删除Parent时,数据库级联删除Child的同时,会自动处理Another表的child_id,就不会再触发IntegrityError了。
内容的提问来源于stack exchange,提问作者gincesoft
相关产品推荐
相关产品推荐

