SQLAlchemy删除父级既不删除子级也不将子级ForeignKey值设置为null

时间:2018-07-15 14:06:55

标签: python sql sqlalchemy

我在SQLAlchemy中有各种各样的一对多关系。删除父项时,我希望其关联的子项也被删除。我尝试使用the docs之后的层叠属性。但是,不仅不删除Children,而且正如我在阅读this question和其他SQLAlchemy讨论后所期望的那样,也没有将其父id设置为null。

这是我的模特:

class Parent(Base):
    __tablename__ = 'parent'
    __table_args__ = {'extend_existing': True}

    id = Column(Integer, primary_key = True)

    children = relationship("Child", order_by=Child.id, backref="parent", cascade="all, delete-orphan")

    def save_to_db(self):
        db_session.add(self)
        db_session.commit()

class Child(Base):
    __tablename__ = 'child'
    __table_args__ = {'extend_existing': True}

    id = Column(Integer, primary_key = True)
    parent_id = Column(Integer, ForeignKey('parent.id')

这是我的删除端点:

    parent = Parent.find_by_id(id)
    deleted = delete(Parent.__table__, Parent.__table__.c.id==id)
    db_session.execute(deleted)
    db_session.commit()

当我第一次创建带有孩子的父母时:

event_info = EventInfo.find_by_id(id)
ids = []
for event in event_info.events:
    ids.append(event.id)
print(str(id) + " Has: "+str(ids)) #prints: 1 has [1]

但是当我删除该父对象,然后与另一个孩子创建另一个父对象时:

    event_info = EventInfo.find_by_id(id)
    ids = []
    for event in event_info.events:
        ids.append(event.id)
    print(str(id) + " Has: "+str(ids)) #prints: 1 has [1,2]. When I print the information of 1, it is the information of the Child created with the original (now deleted) parent.

因此,在删除“父母”然后创建新父母时,“孩子”只是加起来,最后我得到了“父母”中的“父母”,其中有许多旧的,现在已删除的父母。

有什么想法吗?我确定我的人际关系以某种方式配置错误,或者我打算删除错误的内容,但找不到与文档不一致的地方。

1 个答案:

答案 0 :(得分:1)

问题是

[AddMissingContentType]
[HttpDelete]
public async Task<IActionResult> Delete([FromBody]RequestData request)
{
}

是核心的批量操作,尽管它会删除一行。该会话完全不考虑查询的影响,因此ORM级联不适用。如果要使用ORM级联,请使用会话删除实体:

deleted = delete(Parent.__table__, Parent.__table__.c.id==id)
db_session.execute(deleted)

此外,由于您正在使用SQLite,并且如果尚未启用外键约束检查,则数据库允许删除子级引用的父级行。如果需要外键约束检查,则应遵循instructions from the documentation。这个想法是发射

parent = Parent.find_by_id(id)
db_session.delete(parent)

用于新连接。如果希望删除级联,也可以在数据库中添加相同的行为:

PRAGMA foreign_keys=ON

有时候,您可能希望让数据库完全处理级联,尤其是在父实体尚未填充“子”关系的情况下,在这种情况下,您可以在SQLAlchemy中阅读passive deletes