我必须缺少SQLAlchemy的层叠选项的琐碎内容,因为我无法获得简单的层叠删除来正确操作-如果删除了父元素,则子对象将使用null外键保留。
null
我在这里放了一个简洁的测试用例:
from sqlalchemy import Column, Integer, ForeignKey from sqlalchemy.orm import relationship from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Parent(Base): __tablename__ = "parent" id = Column(Integer, primary_key = True) class Child(Base): __tablename__ = "child" id = Column(Integer, primary_key = True) parentid = Column(Integer, ForeignKey(Parent.id)) parent = relationship(Parent, cascade = "all,delete", backref = "children") engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() parent = Parent() parent.children.append(Child()) parent.children.append(Child()) parent.children.append(Child()) session.add(parent) session.commit() print "Before delete, children = {0}".format(session.query(Child).count()) print "Before delete, parent = {0}".format(session.query(Parent).count()) session.delete(parent) session.commit() print "After delete, children = {0}".format(session.query(Child).count()) print "After delete parent = {0}".format(session.query(Parent).count()) session.close()
输出:
Before delete, children = 3 Before delete, parent = 1 After delete, children = 3 After delete parent = 0
父母与子女之间存在简单的一对多关系。该脚本创建一个父级,添加3个子级,然后提交。接下来,它删除父级,但子级仍然存在。为什么?如何使孩子级联删除?
问题是sqlalchemy认为Child是父级的,因为这是您定义关系的地方(当然,不在乎您将其称为“子级”)。
Child
如果在Parent类上定义关系,它将起作用:
Parent
children = relationship("Child", cascade="all,delete", backref="parent")
(请注意"Child"为字符串:使用声明式样式时允许使用,这样您就可以引用尚未定义的类)
"Child"
您可能还想添加delete-orphan(delete导致删除父级时删除子级,delete- orphan也删除从父级“删除”的所有子级,即使未删除父级也是如此)
delete-orphan
delete
delete- orphan
编辑:刚刚发现:如果您 确实 想在Child类上定义关系,则可以这样做,但是您将必须 在backref上 定义级联(通过显式创建backref),如下所示:
parent = relationship(Parent, backref=backref("children", cascade="all,delete"))
(暗示from sqlalchemy.orm import backref)
from sqlalchemy.orm import backref