从自引用继承对象中删除不会在 SQLAlchemy-SQLite 中级联

Deleting from self-referential inherited objects does not cascade in SQLAlchemy-SQLite

我之前 where I tried to build a hierarchy using different objects. Each object can have any type of object as it's parent, and any type as children. I solved it by using the Node class suggested by SQLAlchemy here and letting the other objects inherit 从中发布了一个问题。

现在我遇到了删除节点不会删除其子节点的问题。我已经尝试了很多解决方案,比如不同的级联设置,在外键中使用 ondelete='CASCADE',以及 DBSession.execute('pragma foreign_keys=on') 但 none 正在工作。我认为问题出在 ParentID 键中,因为在删除父项时,在子项中它不为空。

我是 SQLAlchemy 的新手,所以我完全不确定哪里出错了,我们将不胜感激。

这些是我当前的模型:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
# DBSession.execute('pragma foreign_keys=on')
Base = declarative_base()

class Node(Base):
    def getID():
        return uuid.uuid1().hex

    __tablename__ = 'Node'
    ID = Column(Text, primary_key=True, default=getID)
    ParentID = Column(Text, ForeignKey('Node.ID', ondelete='CASCADE'))
    type = Column(Text(50))

    Children = relationship("Node",
                backref=backref('Parent',
                                remote_side=[ID]
                                ),
                single_parent=True,
                cascade="all, delete, delete-orphan",
                passive_deletes = True
            )   
    __mapper_args__ = {
        'polymorphic_identity':'Node',
        'polymorphic_on':type
            }

class A(Node):
    __tablename__ = 'A'
    ID = Column(Text, ForeignKey('Node.ID', ondelete='CASCADE'), primary_key=True)
    Name = Column(Text)
    Description = Column(Text)

    __mapper_args__ = {'polymorphic_identity':'A'}


class B(Node):
    __tablename__ = 'B'
    ID = Column(Text, ForeignKey('Node.ID', ondelete='CASCADE'), primary_key=True)
    Name = Column(Text)
    Description = Column(Text)

    __mapper_args__ = {'polymorphic_identity':'B'}


class C(Node):
    __tablename__ = 'C'
    ID = Column(Text, ForeignKey('Node.ID', ondelete='CASCADE'), primary_key=True)
    Name = Column(Text)
    Description = Column(Text)
    Quantity = Column(Integer)
    Rate = Column(Integer)

    __mapper_args__ = {'polymorphic_identity':'C' }

这就是我构建层次结构的方式:

a = A(Name="PName",
      Description="PDesc",
      ParentID='0')

b = B(Name="BGName",
      Description="BGDesc",
      ParentID=project.ID)

c = C(Name="BIName",
      Description="BIDesc",
      Quantity=10,
      Rate=5,
      ParentID=budgetgroup.ID)

# Append the children nodes to their parents
b.Children.append(c)
a.Children.append(b)
DBSession.add(a)

我是这样删除的:

def deleteitem(id):
        deleteid = id

        deletethis = DBSession.query(Node).filter_by(ID=deleteid).first()
        qry = DBSession.delete(deletethis)
        # qry = DBSession.query(Node).filter_by(ID=deleteid).delete(
        #             synchronize_session='fetch')
        transaction.commit()

注意:一种或另一种方式都没有注释掉删除级联。

我能够从这个答案中找到解决方案 here

现在我的节点 class 如下所示:

class Node(Base):

    __tablename__ = 'Node'
    ID = Column(Integer, primary_key=True)
    ParentID = Column(Integer, ForeignKey('Node.ID', ondelete='CASCADE'))
    type = Column(Text(50))

    Children = relationship(
                'Node',
                cascade="all",
                backref=backref("Parent", remote_side='Node.ID'),
            )

    __mapper_args__ = {
                'polymorphic_identity':'Node',
                'polymorphic_on':type
            }

这似乎有效,我所有的删除都是级联的。