我肯定遗漏了SQLAlChemy的级联选项中一些微不足道的东西,因为我不能让简单的级联删除来正确操作--如果父元素是DELETED元素,则子元素将使用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个子级,然后提交.接下来,它会删除父对象,但子对象会保留.为什么?我该如何让子元素们go 做?

推荐答案

问题是sqlalChemy将Child视为父级,因为这是您定义关系的位置(当然,它不在乎您将其称为"子级").

如果改为在Parent类上定义关系,它将起作用:

children = relationship("Child", cascade="all,delete", backref="parent")

(注意"Child"作为字符串:在使用声明式样式时,这是允许的,因此您可以引用尚未定义的类)

您可能还需要添加delete-orphan(delete会在删除父项时删除子项,delete-orphan还会删除从父项中"删除"的所有子项,即使父项未被删除)

编辑:刚刚发现:如果really想在Child类上定义关系,可以这样做,但您必须定义级联on the backref(通过显式创建backref),如下所示:

parent = relationship(Parent, backref=backref("children", cascade="all,delete"))

(隐含from sqlalchemy.orm import backref个)

Database相关问答推荐

网络分区恢复后副本的更新数据发生了什么

实体关系图. IS A 关系如何转换为table表?

一个强大的 MySQL 管理工具,具有与 SQL Server Management Studio 类似的功能

如何将 Grails 3.0 连接到我的本地 Mysql 数据库

在 PostgreSQL 的数组列中查找字符串

什么技术对处理数百万条记录最有效?

在 Oracle 的 Check 语句中使用子查询

ODBC 与 JDBC 与 ADO.NET

触发器内的多个插入/更新语句?

ER图中的一对多关系

锁定机制(悲观/乐观)如何与数据库事务隔离级别相关?

当另一个进程修改数据库时Hibernate二级缓存失效

不带 WHERE 子句的 UPDATE 查询

如何使用 MySQL Workbench 架构差异两个数据库?

使用 PHP/PDO 判断数据库表是否存在

Python中准备好的语句和参数化查询之间的混淆

使用 C3P0 的 JDBC 连接池

Firebase 排行榜排名

将查询限制为一条记录会提高性能吗

从 SQLite 导出到 SQL Server