1

我有一个情况,我的两个数据库表的外键指向对方。这是通过 MySQL 通过 SQLAlchemy。我想这样做,以便当我删除父项时,所有子行都被删除。我的架构(简化)如下所示:

Parent(id, child_id, another_child_id)

Child(id, parent_id)

ondelete='CASCADE'在子模型定义中设置了父关系。

根据SQLAlchemy 文档的这一部分,您需要做的就是设置post-update,这应该会为您处理删除子项,而不会遇到键约束错误。

不幸的是,我认为我的情况很奇怪,因为我在 Parent 中有两列指向 Child,这与文档中的示例不同。当我尝试删除父级时,父级中的以下关系配置给我一个外键约束错误(因为parent_id取决于父级存在):

child = relationship('Child', 
    primaryjoin='Child.id==Article.child_id',
    post_update=True)
another_child = relationship('Child', 
    primaryjoin='Child.id==Article.another_child_id',
    post_update=True)

我可以让它工作的唯一方法是cascade='delete'在任一列上放置一个标志:

child = relationship('Child', 
    primaryjoin='Child.id==Article.child_id',
    post_update=True,
    cascade='delete')
another_child = relationship('Child', 
    primaryjoin='Child.id==Article.another_child_id',
    post_update=True)

奇怪的是,当我把cascade='delete'两列都放在上面时,就会出现各种各样的问题。例如:

c = Child()
p = Parent()
p.child = c
p.another_child = c
session.add(p)
session.commit()

上面的代码将在数据库中创建一个 Parent,但child_idanother_child_id列是 NULL。甚至从未创建子行。

谁能解释为什么cascade='delete'能够解决我的级联删除问题,而不是仅仅ondelete='CASCADE'在子外键上?另外,为什么它仅在设置在其中一个关系而不是两者上时才起作用(这对我来说似乎更合乎逻辑)?

4

0 回答 0