摘要:上一篇文章第節(jié)關(guān)系操作級聯(lián)是在一對多關(guān)系中父表與子表進行聯(lián)動操作的數(shù)據(jù)庫術(shù)語。注意級聯(lián)獨立于本身針對外鍵的級聯(lián)定義。代碼執(zhí)行后數(shù)據(jù)庫表中的內(nèi)容的變化表五年二班理想路號樓表理想男靜安區(qū)女靜安區(qū)小馬哥女閘口區(qū)張三韓永躍男靜安區(qū)
上一篇文章:Python-SQLAlchemy:第3節(jié):關(guān)系操作
級聯(lián)是在一對多關(guān)系中父表與子表進行聯(lián)動操作的數(shù)據(jù)庫術(shù)語。因為父表與子表通過外鍵關(guān)聯(lián),所以對父表或子表的增、刪、改操作會對另一張表產(chǎn)生相應(yīng)的影響。適當(dāng)?shù)睦眉壜?lián)可以開發(fā)出更優(yōu)雅、健壯的數(shù)據(jù)庫程序。本節(jié)學(xué)習(xí)SQLAlchemy中級聯(lián)的操作方法。
注意:SQLAlchemy級聯(lián)獨立于SQL本身針對外鍵的級聯(lián)定義。即使在數(shù)據(jù)庫表定義中沒有定義on delete等屬性,也不影響開發(fā)者在SQLAlchemy中使用級聯(lián)。1、級聯(lián)定義
SQLAlchemy中的級聯(lián)通過對父表中的relationship屬性定義cascade參數(shù)來實現(xiàn),代碼如下:
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(父表)和學(xué)生表Student(子表)。一對多的關(guān)系有父表中的relationship屬性students進行定義。relationship中的cascade參數(shù)定義了要在該關(guān)系上實現(xiàn)的級聯(lián)方法為:all。
SQLAlchemy中另外一種設(shè)置級聯(lián)的方式是在子表的relationship的backref中進行設(shè)置。比如上述代碼可以寫為如下形式,意義保持不變:
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中設(shè)置relationship和cascade,而是在子表中設(shè)置了。
SQLAlchemy中可選的cascade取值范圍如下表所示:
可選值 | 意義 |
---|---|
save-update | 當(dāng)一個父對象被新增到session中時,該對象當(dāng)時關(guān)聯(lián)的子對象也自動被新增到session中。 |
merge | Session.merge是一個對數(shù)據(jù)庫對象進行新增或更新的辦法。cascade取值為merge時的意義為:當(dāng)父對象進行merge操作時,該對象當(dāng)時關(guān)聯(lián)的子對象也會被merge |
expunge | Session.expunge是一種將對象從session中移除的方法。cascade取值為expunge時的意義為:當(dāng)父對象進行了expunge操作時,該對象當(dāng)時關(guān)聯(lián)的子對象也會被從session中刪除。 |
delete | 當(dāng)父對象被delete時,會自動將該子對象刪除 |
delete-orphan | 當(dāng)子對象不再與任何父對象關(guān)聯(lián)時,會自動將該子對象刪除 |
refresh-expire | Session.expire是一種設(shè)置對象已過期、下次引用時需要從數(shù)據(jù)庫即時讀取的方法。cascade取值為refredh-expire時的意義為:當(dāng)父對象進行了expire操作時,該對象當(dāng)時關(guān)聯(lián)的子對象也進行expire操作。 |
all | 是一個集合值,表示:save-update、merge、refresh-expire、expunge、delete同時被設(shè)置 |
多個cascade屬性可以通過逗號分隔并同時賦值給cascade。例如:
students=relationship("Student",backref="class_",cascade="save-update,merge,expunge")
在默認情況下,任何relationship的級聯(lián)屬性都被設(shè)置為cascade="save-update,merge"。下面就常用的參數(shù):save-update、delet、delete-orphan的功能進行舉例說明。
2、save-update級聯(lián)save-update級聯(lián)是指當(dāng)一個父對象被新增到session中時,該對象當(dāng)時關(guān)聯(lián)的子對象也自動被新增到session中。
通過如下代碼建立一個父對象class和兩個子對象students1與students2
class_=Class() student1,student2=Student(),Student() class_.students.append(student1) class_.students.append(student2)
如果父子級聯(lián)關(guān)系包含save-update,則只需要將父對象保存到session中,子對象會自動被保存。
session.add(class_) if student1 in session: print("The student1 has been added too!")
上面代碼將會打?。?The student1 has been added too!"
技巧:”in“語句可以判斷某對象是否被關(guān)聯(lián)到了session中。已被關(guān)聯(lián)的對象在session被commit時會被寫入到視頻庫中。
即使父對象已經(jīng)被新增到session中,新關(guān)聯(lián)的子對象仍然可以被添加:
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級聯(lián)顧名思義,delete級聯(lián)是指當(dāng)父對象被從session中刪除時,其關(guān)聯(lián)的子對象也自動被從session中delete。通過一個例子演示delete的作用,假設(shè)數(shù)據(jù)庫中class表和students表的內(nèi)容如下表所示:
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 | 男 | 靜安區(qū) | Null |
2 | 1 | mark | 10 | 女 | 靜安區(qū) | Null |
3 | 1 | 小馬哥 | 9 | 女 | 閘口區(qū) | 張三 |
4 | 2 | 張苗 | 10 | 男 | 寶山區(qū) | NULL |
5 | 2 | 小黑 | 12 | 女 | 靜安區(qū) | 李四 |
6 | 2 | 喵喵 | 11 | 男 | 閘北區(qū) | NULL |
7 | 1 | 韓永躍 | 10 | 男 | 靜安區(qū) | NULL |
8 | 3 | 小鏡鏡 | 12 | 男 | 閘北區(qū) | NULL |
9 | 3 | 小鏡子 | 12 | 女 | 寶山區(qū) | NULL |
從例表中可知,系統(tǒng)中有3個班級,他們分別有4、3、2個學(xué)生。如果SQLAlchemy中沒有把它們的relationship的cascade設(shè)置為delete,則刪除父表內(nèi)容不會刪除相應(yīng)的子表內(nèi)容,而是把子表的相應(yīng)外鍵設(shè)置為空。比如:
class_=session.query(Class).filter(name="三年二班").first() #三年二班的class_id為1 session.delete(class_) #刪除class_id為1的班級
當(dāng)cascade不包含delete時,上述代碼中的delete語句相當(dāng)于執(zhí)行了如下SQL語句:
UPDATE student SET class_id=None WHERE class_id=1; DELETE FROM class WHERE class_id=1; COMMIT;
執(zhí)行后數(shù)據(jù)表class和student的內(nèi)容變化如下所示:
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 | 男 | 靜安區(qū) | Null |
2 | NULL | mark | 10 | 女 | 靜安區(qū) | Null |
3 | NULL | 小馬哥 | 9 | 女 | 閘口區(qū) | 張三 |
4 | 2 | 張苗 | 10 | 男 | 寶山區(qū) | NULL |
5 | 2 | 小黑 | 12 | 女 | 靜安區(qū) | 李四 |
6 | 2 | 喵喵 | 11 | 男 | 閘北區(qū) | NULL |
7 | 1 | 韓永躍 | 10 | 男 | 靜安區(qū) | NULL |
8 | 3 | 小鏡鏡 | 12 | 男 | 閘北區(qū) | NULL |
9 | 3 | 小鏡子 | 12 | 女 | 寶山區(qū) | NULL |
此時將表定義中的relationship的cascade屬性設(shè)置為delete:
students=relationship("Student",backref="class",cascade="delete")
現(xiàn)在通過如下語句刪除“五年一班”:
class_=session.query(Class).filter(name="五年一班").first() #五年一班的class_id為2 session.delete(class_) #刪除class_id為2的班級
當(dāng)cascade包含“delete”時,上述代碼中的delete語句相當(dāng)于執(zhí)行了如下SQL語句:
DELETE FROM student WHERE class=2; DELETE FROM class WHERE class=2; COMMIT;
執(zhí)行后數(shù)據(jù)庫表class和student的內(nèi)容變化如下表所示:
class表:
class_id | name | level | address |
---|---|---|---|
3 | 五年二班 | 5 | 理想路520號3樓 |
student表:
student_id | class_id | name | age | gender | address | contactor |
---|---|---|---|---|---|---|
1 | NULL | 理想 | 10 | 男 | 靜安區(qū) | Null |
2 | NULL | mark | 10 | 女 | 靜安區(qū) | Null |
3 | NULL | 小馬哥 | 9 | 女 | 閘口區(qū) | 張三 |
7 | NULL | 韓永躍 | 10 | 男 | 靜安區(qū) | NULL |
8 | 3 | 小鏡鏡 | 12 | 男 | 閘北區(qū) | NULL |
9 | 3 | 小鏡子 | 12 | 女 | 寶山區(qū) | NULL |
delete-orphan級聯(lián)是指當(dāng)子對象不再與任何父對象關(guān)聯(lián)時,會自動將該子對象刪除。設(shè)置父表與子表的relationship中的cascade包含“delete-orphan”:
students=relationship("Student",backref="class",cascade="delete-orphan")
通過如下代碼將于班級“五年一班”關(guān)聯(lián)的學(xué)生全部脫離:
class_=session.query(Class).filter(name="五年二班").first() unattachedStudent=[] while len(class_.students)>0: unattachedStudent.append(class_.students.pop()) #與父對象脫離 session.commit #顯示地提交事務(wù)
上述代碼中沒有顯示地刪除任何學(xué)生,但由于使用了delete-orphan級聯(lián),所以被脫離出班級對象的學(xué)生會在session事務(wù)提交時會自動從數(shù)據(jù)庫中刪除。代碼執(zhí)行后數(shù)據(jù)庫表中的內(nèi)容的變化:
class表:
class_id | name | level | address |
---|---|---|---|
3 | 五年二班 | 5 | 理想路520號3樓 |
student表:
student_id | class_id | name | age | gender | address | contactor |
---|---|---|---|---|---|---|
1 | NULL | 理想 | 10 | 男 | 靜安區(qū) | Null |
2 | NULL | mark | 10 | 女 | 靜安區(qū) | Null |
3 | NULL | 小馬哥 | 9 | 女 | 閘口區(qū) | 張三 |
7 | NULL | 韓永躍 | 10 | 男 | 靜安區(qū) | NULL |
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/44879.html
摘要:本節(jié)圍繞在中如何定義關(guān)系及如何使用關(guān)系進行查詢進行講解,使讀者能夠快速掌握的關(guān)系操作。班級與學(xué)生為一對多關(guān)系,班級與老師之間為多對多關(guān)系。三年二班多對多關(guān)系的使用通過關(guān)聯(lián)模型實現(xiàn),在其中分別設(shè)置模型和的外鍵,并且在父模型中設(shè)置相應(yīng)的實現(xiàn)。 上一篇文章:Python-SQLAlchemy:第2節(jié):查詢條件設(shè)置下一篇文章:Python-SQLAlchemy:第4節(jié):級聯(lián) 關(guān)系數(shù)據(jù)庫是建立...
摘要:上一篇文章第節(jié)入門下一篇文章第節(jié)關(guān)系操作在實際編程中需要根據(jù)各種不同的條件查詢數(shù)據(jù)庫記錄,查詢條件被稱為過濾器。通配符用百分號表示。以下條語句查詢結(jié)果相同,都是為的記錄。引入或邏輯關(guān)鍵字查詢是或者為的記錄,返回結(jié)果為為的記錄 上一篇文章:Python-SQLAlchemy:第1節(jié):SQLAlchemy入門下一篇文章:Python-SQLAlchemy:第3節(jié):關(guān)系操作 在實際編程中需...
摘要:下一篇文章第節(jié)查詢條件設(shè)置是編程語言下的一款開源軟件。提供了工具包及對象關(guān)系映射工具,使用許可證發(fā)行。在關(guān)閉連接時會自動進行事務(wù)提交操作。引入多條件查詢時使用。由于上下文函數(shù)退出時會自動提交事務(wù),所以無需顯示的調(diào)用使新增生效。 下一篇文章:Python-SQLAlchemy:第2節(jié):查詢條件設(shè)置 SQLAlchemy是Python編程語言下的一款開源軟件。提供了SQL工具包及對象關(guān)系...
摘要:因為是工作在一個內(nèi)部,有時候我們可能不小心做了一些誤刪除的操作,可以回滾。我們先修改的用戶名為,然后重新添加一個新,但是記住這個時候我們還沒有。集合類型可以是各種合法類型,比如,但是默認集合是一個。 官方文檔 Initialization # 檢查是否已經(jīng)安裝以及版本號 >>> import sqlalchemy >>> sqlalchemy.__version__ ’1.1.4‘ ...
閱讀 3563·2023-04-26 02:48
閱讀 1530·2021-10-11 10:57
閱讀 2551·2021-09-23 11:35
閱讀 1267·2021-09-06 15:02
閱讀 3367·2019-08-30 15:54
閱讀 1691·2019-08-30 15:44
閱讀 952·2019-08-30 15:44
閱讀 1042·2019-08-30 12:52