代码之家  ›  专栏  ›  技术社区  ›  Toby Weed

SQLAlchemy删除父项既不删除子项也不将子项ForeignKey值设置为空

  •  0
  • Toby Weed  · 技术社区  · 7 年前

    我在sqlacalchemy中有各种一对多的关系。当我删除父条目时,我希望它的关联子条目也被删除。我尝试使用以下cascade属性 the docs 。然而,不仅是未被删除的子代,而且它们的父代ID也没有设置为空,正如我在阅读后所期望的那样。 this question 以及其他有关SQLAlchemy的讨论。

    以下是我的模型:

    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 回复  |  直到 7 年前
        1
  •  1
  •   Ilja Everilä    7 年前

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

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

    instructions from the documentation

    PRAGMA foreign_keys=ON
    

    class Child(Base):
        ...
        parent_id = Column(Integer, ForeignKey('parent.id', ondelete='CASCADE'))
    

    passive deletes