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

时间:2015-03-03 22:29:15

标签: python sqlite inheritance sqlalchemy cascade

我之前发布了一个问题here,我尝试使用不同的对象构建层次结构。每个对象可以具有任何类型的对象,因为它是父对象,任何类型都可以作为子对象。我通过使用SQLAlchemy here建议的Node类并让其他对象inherit从中解决它。

现在我遇到的问题是删除节点不会删除它的子节点。我尝试了很多解决方案,比如不同的级联设置,在外键中使用ondelete='CASCADE',以及DBSession.execute('pragma foreign_keys=on'),但没有一个正在运行。我认为问题出在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()

注意:单向或其他方式都没有删除级联。

1 个答案:

答案 0 :(得分:1)

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

现在我的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
            }

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