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



我之前在这里发布了一个问题,我试图使用不同的对象构建层次结构。每个对象都可以有任何类型的对象作为其父对象,也可以有任意类型的子对象。我在这里使用了SQLAlchemy建议的Node类,并让其他对象从中继承,从而解决了这个问题

现在我遇到的问题是,删除一个节点不会删除它的子节点。我尝试了很多解决方案,比如不同的级联设置,在外键中使用ondelete='CASCADE'DBSession.execute('pragma foreign_keys=on'),但都不起作用。我认为问题出在ParentID键上,因为在子项中,当删除父项时,它不为null。

我是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()

注意:无论是一种方式还是另一种方式都没有注释掉删除级联。

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

现在我的Node类如下所示:

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
            }

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

最新更新