摘要:上一篇文章第節關系操作級聯是在一對多關系中父表與子表進行聯動操作的數據庫術語。注意級聯獨立于本身針對外鍵的級聯定義。代碼執行后數據庫表中的內容的變化表五年二班理想路號樓表理想男靜安區女靜安區小馬哥女閘口區張三韓永躍男靜安區
上一篇文章: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_base Base=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_base Base=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 |
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 |
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/44879.html
摘要:本節圍繞在中如何定義關系及如何使用關系進行查詢進行講解,使讀者能夠快速掌握的關系操作。班級與學生為一對多關系,班級與老師之間為多對多關系。三年二班多對多關系的使用通過關聯模型實現,在其中分別設置模型和的外鍵,并且在父模型中設置相應的實現。 上一篇文章:Python-SQLAlchemy:第2節:查詢條件設置下一篇文章:Python-SQLAlchemy:第4節:級聯 關系數據庫是建立...
摘要:上一篇文章第節入門下一篇文章第節關系操作在實際編程中需要根據各種不同的條件查詢數據庫記錄,查詢條件被稱為過濾器。通配符用百分號表示。以下條語句查詢結果相同,都是為的記錄。引入或邏輯關鍵字查詢是或者為的記錄,返回結果為為的記錄 上一篇文章:Python-SQLAlchemy:第1節:SQLAlchemy入門下一篇文章:Python-SQLAlchemy:第3節:關系操作 在實際編程中需...
摘要:下一篇文章第節查詢條件設置是編程語言下的一款開源軟件。提供了工具包及對象關系映射工具,使用許可證發行。在關閉連接時會自動進行事務提交操作。引入多條件查詢時使用。由于上下文函數退出時會自動提交事務,所以無需顯示的調用使新增生效。 下一篇文章:Python-SQLAlchemy:第2節:查詢條件設置 SQLAlchemy是Python編程語言下的一款開源軟件。提供了SQL工具包及對象關系...
摘要:因為是工作在一個內部,有時候我們可能不小心做了一些誤刪除的操作,可以回滾。我們先修改的用戶名為,然后重新添加一個新,但是記住這個時候我們還沒有。集合類型可以是各種合法類型,比如,但是默認集合是一個。 官方文檔 Initialization # 檢查是否已經安裝以及版本號 >>> import sqlalchemy >>> sqlalchemy.__version__ ’1.1.4‘ ...
閱讀 3475·2023-04-26 02:48
閱讀 1472·2021-10-11 10:57
閱讀 2497·2021-09-23 11:35
閱讀 1204·2021-09-06 15:02
閱讀 3302·2019-08-30 15:54
閱讀 1619·2019-08-30 15:44
閱讀 887·2019-08-30 15:44
閱讀 994·2019-08-30 12:52