级联在SQLAlchemy中的相互依赖表中删除

时间:2013-06-07 06:39:56

标签: orm sqlalchemy foreign-keys cascade sql-delete

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

Parent(id, child_id, another_child_id)

Child(id, parent_id)

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

根据SQLAlchemy文档中的this section,您需要做的就是设置post-update,这可能会处理为您删除子项而不会遇到键约束错误。

不幸的是,我认为我的情况很奇怪,因为我在Parent中有两个指向Child的列,这与docs中的示例不同。当我尝试删除父项时,Parent中的以下关系配置给出了外键约束错误(因为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'吗?另外,为什么只有当它设置在一个关系而不是两个关系上时它才起作用(这对我来说似乎更符合逻辑)?

0 个答案:

没有答案