上一篇文章:Python-SQLAlchemy:第3节:关系操作

级联是在一对多关系中父表与子表进行联动操作的数据库术语。因为父表与子表通过外键关联,所以对父表或子表的增、删、改操作会对另一张表产生相应的影响。适当的利用级联可以开发出更优雅、健壮的数据库程序。本节学习SQLAlchemy中级联的操作方法。

注意:SQLAlchemy级联独立于SQL本身针对外键的级联定义。即使在数据库表定义中没有定义on delete等属性,也不影响开发者在SQLAlchemy中使用级联。

1、级联定义

SQLAlchemy中的级联通过对父表中的relationship属性定义cascade参数来实现,代码如下:

from sqlalchemy import Table,Column,Integer,ForeignKey,String
from sqlalchemy.orm import relationship,backref
from sqlalchemy.ext.declarative import declarative_baseBase=declarative_base()class Class(Base):__tablename__='class'class_id=Column(Integer,primary_key=True)name=Column(String(50))level=Column(Integer)address=Column(String(50))students=relationship("Student",backref="class_",cascade="all")class Student(Base):__tablename__='student'student_id=Column(Integer,primary_key=True)name=Column(String(50))age=Column(Integer)gender=Column(String(10))address=Column(String(50))class_id=Column(Integer,ForeignKey('class.class_id'))

上述代码定义了班级表Class(父表)和学生表Student(子表)。一对多的关系有父表中的relationship属性students进行定义。relationship中的cascade参数定义了要在该关系上实现的级联方法为:all。

SQLAlchemy中另外一种设置级联的方式是在子表的relationship的backref中进行设置。比如上述代码可以写为如下形式,意义保持不变:

from sqlalchemy import Table,Column,Integer,ForeignKey,String
from sqlalchemy.orm import relationship,backref
from sqlalchemy.ext.declarative import declarative_baseBase=declarative_base()class Class(Base):__tablename__='class'class_id=Column(Integer,primary_key=True)name=Column(String(50))level=Column(Integer)address=Column(String(50))
class Student(Base):__tablename__='student'student_id=Column(Integer,primary_key=True)name=Column(String(50))age=Column(Integer)gender=Column(String(10))address=Column(String(50))class_id=Column(Integer,ForeignKey('class.class_id'))class_=relationship("Class",backref="students",cascade="all")

上述代码没有在父表Class中设置relationship和cascade,而是在子表中设置了。

SQLAlchemy中可选的cascade取值范围如下表所示:

可选值 意义
save-update 当一个父对象被新增到session中时,该对象当时关联的子对象也自动被新增到session中。
merge Session.merge是一个对数据库对象进行新增或更新的办法。cascade取值为merge时的意义为:当父对象进行merge操作时,该对象当时关联的子对象也会被merge
expunge Session.expunge是一种将对象从session中移除的方法。cascade取值为expunge时的意义为:当父对象进行了expunge操作时,该对象当时关联的子对象也会被从session中删除。
delete 当父对象被delete时,会自动将该子对象删除
delete-orphan 当子对象不再与任何父对象关联时,会自动将该子对象删除
refresh-expire Session.expire是一种设置对象已过期、下次引用时需要从数据库即时读取的方法。cascade取值为refredh-expire时的意义为:当父对象进行了expire操作时,该对象当时关联的子对象也进行expire操作。
all 是一个集合值,表示:save-update、merge、refresh-expire、expunge、delete同时被设置

多个cascade属性可以通过逗号分隔并同时赋值给cascade。例如:

students=relationship("Student",backref="class_",cascade="save-update,merge,expunge")

在默认情况下,任何relationship的级联属性都被设置为cascade="save-update,merge"。下面就常用的参数:save-update、delet、delete-orphan的功能进行举例说明。

2、save-update级联

save-update级联是指当一个父对象被新增到session中时,该对象当时关联的子对象也自动被新增到session中。

通过如下代码建立一个父对象class和两个子对象students1与students2

class_=Class()
student1,student2=Student(),Student()
class_.students.append(student1)
class_.students.append(student2)

如果父子级联关系包含save-update,则只需要将父对象保存到session中,子对象会自动被保存。

session.add(class_)
if student1 in session:print("The student1 has been added too!")

上面代码将会打印:"The student1 has been added too!"

技巧:”in“语句可以判断某对象是否被关联到了session中。已被关联的对象在session被commit时会被写入到视频库中。

即使父对象已经被新增到session中,新关联的子对象仍然可以被添加:

class_=Class()
session.add(class_)
students3=Student()
if student3 in session:print("The student3 is added before append to the class_!")
class_.students.append(students)
if student1 in session:print("The student3 is added after append to the class_!")

这段代码打印”The student3 is added after append to the class_!“

3、delete级联

顾名思义,delete级联是指当父对象被从session中删除时,其关联的子对象也自动被从session中delete。通过一个例子演示delete的作用,假设数据库中class表和students表的内容如下表所示:

class表:

class_id name level address
1 三年二班 3 理想路520号1楼
2 五年一班 5 理想路520号3楼
3 五年二班 5 理想路520号3楼

student表:

student_id class_id name age gender address contactor
1 1 理想 10 静安区 Null
2 1 mark 10 静安区 Null
3 1 小马哥 9 闸口区 张三
4 2 张苗 10 宝山区 NULL
5 2 小黑 12 静安区 李四
6 2 喵喵 11 闸北区 NULL
7 1 韩永跃 10 静安区 NULL
8 3 小镜镜 12 闸北区 NULL
9 3 小镜子 12 宝山区 NULL

从例表中可知,系统中有3个班级,他们分别有4、3、2个学生。如果SQLAlchemy中没有把它们的relationship的cascade设置为delete,则删除父表内容不会删除相应的子表内容,而是把子表的相应外键设置为空。比如:

class_=session.query(Class).filter(name="三年二班").first() #三年二班的class_id为1
session.delete(class_) #删除class_id为1的班级

当cascade不包含delete时,上述代码中的delete语句相当于执行了如下SQL语句:

UPDATE student SET class_id=None WHERE class_id=1;
DELETE FROM class WHERE class_id=1;
COMMIT;

执行后数据表class和student的内容变化如下所示:

class表:

class_id name level address
2 五年一班 5 理想路520号3楼
3 五年二班 5 理想路520号3楼

student表:

student_id class_id name age gender address contactor
1 NULL 理想 10 静安区 Null
2 NULL mark 10 静安区 Null
3 NULL 小马哥 9 闸口区 张三
4 2 张苗 10 宝山区 NULL
5 2 小黑 12 静安区 李四
6 2 喵喵 11 闸北区 NULL
7 1 韩永跃 10 静安区 NULL
8 3 小镜镜 12 闸北区 NULL
9 3 小镜子 12 宝山区 NULL

此时将表定义中的relationship的cascade属性设置为delete:

students=relationship("Student",backref="class",cascade="delete")

现在通过如下语句删除“五年一班”:

class_=session.query(Class).filter(name="五年一班").first() #五年一班的class_id为2
session.delete(class_) #删除class_id为2的班级

当cascade包含“delete”时,上述代码中的delete语句相当于执行了如下SQL语句:

DELETE FROM student WHERE class=2;
DELETE FROM class WHERE class=2;
COMMIT;

执行后数据库表class和student的内容变化如下表所示:

class表:

class_id name level address
3 五年二班 5 理想路520号3楼

student表:

student_id class_id name age gender address contactor
1 NULL 理想 10 静安区 Null
2 NULL mark 10 静安区 Null
3 NULL 小马哥 9 闸口区 张三
7 NULL 韩永跃 10 静安区 NULL
8 3 小镜镜 12 闸北区 NULL
9 3 小镜子 12 宝山区 NULL

4、delete-orphan级联

delete-orphan级联是指当子对象不再与任何父对象关联时,会自动将该子对象删除。设置父表与子表的relationship中的cascade包含“delete-orphan”:

students=relationship("Student",backref="class",cascade="delete-orphan")

通过如下代码将于班级“五年一班”关联的学生全部脱离:

class_=session.query(Class).filter(name="五年二班").first()
unattachedStudent=[]
while len(class_.students)>0:unattachedStudent.append(class_.students.pop()) #与父对象脱离
session.commit #显示地提交事务

上述代码中没有显示地删除任何学生,但由于使用了delete-orphan级联,所以被脱离出班级对象的学生会在session事务提交时会自动从数据库中删除。代码执行后数据库表中的内容的变化:

class表:

class_id name level address
3 五年二班 5 理想路520号3楼

student表:

student_id class_id name age gender address contactor
1 NULL 理想 10 静安区 Null
2 NULL mark 10 静安区 Null
3 NULL 小马哥 9 闸口区 张三
7 NULL 韩永跃 10 静安区 NULL

Python-SQLAlchemy:第4节:级联相关推荐

  1. Python SQLAlchemy

    一.写在前面 这篇文章主要介绍了Python的SQLAlchemy框架使用入门,SQLAlchemy框架是Python中用来操作数据库的ORM框架之一,学习过程中主要参考网上现有资料,整理成笔记以便后 ...

  2. 使用Python,OpenCV和Haar级联进行人脸检测——轻量级的人脸检测器

    使用Python,OpenCV和Haar级联进行人脸检测--轻量级的人脸检测器 1. 效果图 2. 原理 2.1 项目结构 2.2 [haarcascade_frontalface_default.x ...

  3. python sqlalchemy操作SQLite

    日期转时间: from sqlalchemy import Column, Integer, String, Float, Date date = Column(Date) data="20 ...

  4. Python SqlAlchemy使用方法

    1.初始化连接 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create ...

  5. Python SQLAlchemy入门教程

    原文:https://www.cnblogs.com/ybjourney/p/11832045.html Python SQLAlchemy入门教程 一.介绍 关于ORM 为什么用sqlalchemy ...

  6. Python SQLAlchemy --3

    本文為 Python SQLAlchemy ORM 一系列教學文: 刪除 學會如何查詢之後,就能夠進行後續的刪除.更新等操作. 同樣地,以幾個範例做為學習的捷徑. 123456789 user_1 = ...

  7. 微课|中学生可以这样学Python(8.1节):解析算法例题讲解

    适用教材: 董付国,应根球.<中学生可以这样学Python>.清华大学出版社,2017. 第8章  常用算法的Python实现 8.1  解析算法案例分析 京东购买链接:https://i ...

  8. 微课|中学生可以这样学Python(8.3节):递推算法例题讲解

    适用教材: 董付国,应根球.<中学生可以这样学Python>.清华大学出版社,2017. 第8章  常用算法的Python实现 8.3  递推算法案例分析 京东购买链接:https://i ...

  9. 微课|中学生可以这样学Python(8.4节):递归算法例题讲解2

    适用教材: 董付国,应根球.<中学生可以这样学Python>.清华大学出版社,2017. 第8章  常用算法的Python实现 8.4  递归算法案例分析 京东购买链接:https://i ...

  10. 微课|中学生可以这样学Python(8.4节):递归算法例题讲解3

    适用教材: 董付国,应根球.<中学生可以这样学Python>.清华大学出版社,2017. 第8章  常用算法的Python实现 8.4  递归算法案例分析 京东购买链接:https://i ...

最新文章

  1. C# 依据鼠标坐标取网页内成员坐标.ie
  2. 【简洁代码】1053 住房空置率 (20分)_22行代码AC
  3. Maven--反应堆(Reactor)
  4. python如何改变数据类型_如何改变numpy数组的数据类型和形状?
  5. Listview的OnScrollListener的滑动监听实现分页加载
  6. [开源应用]利用HTTPHandler+resumableJs+HTML5实现拖拽上传[大]文件
  7. 设计模式笔记八:过滤器模式
  8. 11gR2 集群(CRS/GRID)新功能—— SCAN(Single Client Access Name)
  9. codevs 1576 最长上升子序列的线段树优化
  10. 松下伺服电机uvw接线图_松下Panasonic伺服电机电源线选择与接线方法
  11. 读npy、pck、nii格式数据集
  12. Windows网络连接指示器,NCSI
  13. UPC9575 鑫鑫的算术
  14. vue项目怎么修改项目名称
  15. 2022总结,强风吹拂
  16. 抖音短视频数据抓取实战系列(九)——自动化Appium的环境与参数配置
  17. Matter将带来统一的视频投射方式——由亚马逊领导的电视视频投射标准将挑战Apple AirPlay和Google Cast
  18. 使用Excel对国外B2B电商平台进行描述性数据分析
  19. JavaScript诞生二十年,作者Brendan Eich自述10天内开发出JS语言
  20. “网上购车平台”又出新模式

热门文章

  1. 华为自动驾驶实车实路测试视频曝光!
  2. 机器学习研究者必知的八个神经网络架构
  3. 倪光南:看好鸿蒙系统,坚持生态体系创新才能不被“卡脖子”
  4. 概述自动机器学习(AutoML)
  5. 前沿地带:从量子计算到量子互联网
  6. 华为生态链的全方位解读
  7. 字节跳动教育裁员:赔付方式N+2
  8. 漫画:什么是 JVM 的垃圾回收?
  9. 什么工作,未来可以走创业路线?
  10. 彩蛋还是陷阱?我所经历的期权往事