一、關於級聯刪除
1.在表的外鍵中設置CASCADE, 可以進行級聯刪除。
級聯刪除是刪除父表時發揮作用。相同的列,做外鍵的是子表,做主鍵的是父表,子表是引用父表的 應該子表不能影響到父表的結果
fk_vnf_id = db.Column(db.String(50), db.ForeignKey('vnf.vnf_id', ondelete="CASCADE"),index=True)
在flask中兩表關係是一對多。目的:刪除一的同時 多也同時 刪除
一的一方通過relationship關聯到多的一方,多的一方設置ForeignKey關聯到一的一方。如果沒設置外鍵就直接設置relationshiip 會報錯。
例子1:
Flask中使用ORM時候,如果刪除了父記錄希望級聯刪除字對象的話,需要在反向關係中添加cascade='all, delete-orphan'參數
在這裏假設一個person對應多個books,實列如下:
class Person(db.Model) :
__tablename__ = 'persons'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(32))
# 添加cascade='all, delete-orphan'參數
books = db.relationship('Book', backref='device', lazy='dynamic',cascade='all, delete-orphan')
class Book(db.Model) :
__tablename__ = 'books '
id = db.Column(db.Integer, primary_key = True)-
name = db.Column(db.String(32))
# 外鍵添加ondelete='CASCADE')屬性
device_id = db.Column(db.Integer, db.ForeignKey('persons.id',ondelete='CASCADE'))
一的一方:
cascade='all, delete-orphan'
多的一方:
# 在ForeignKey中加上ondelete='CASCADE'
db.ForeignKey( ondelete='CASCADE')
例子2:
一對多關係,User爲一,Task爲多。
一的一方通過relationship關聯到多的一方,多的一方設置ForeignKey關聯到一的一方。
relationship中設置cascade=‘all, delete-orphan’ 與 passive_deletes = True,
ForeignKey中設置ondelete = ‘CASCADE’。
即可完成刪除User的同時,刪除與該user對象相關的task對象。
例如:
user的id爲1,同時任務列表中,任務id爲1和2的兩個任務的user_id爲1,即user中id爲1的用戶擁有任務id爲1和2的兩個任務。通過刪除id爲1的user,任務表中id爲1和2的兩個task對象也會同時刪除。
作者:Cichar
鏈接:https://www.jianshu.com/p/ac065ac70f34
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
from . import db
class User(db.Model):
__tablesname__ = 'users'
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), unique = True)
tasks = db.relationship('Task', backref='user', lazy='dynamic', cascade='all, delete-orphan', passive_deletes = True)
def __repr__(self):
return '<User %r>' % self.username
class Task(db.Model):
__tablesname__ = 'tasks'
id = db.Column(db.Integer, primary_key = True)
taskname = db.Column(db.String(64), unique = True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'))
def __repr__(self):
return '<Task %r>' % self.taskname
二、關於外鍵
外鍵的形式有一對一, 一對多, 多對多
因爲外鍵(ForeignKey)始終定義在多的一方.如果relationship定義在多的一方,那就是多對一,一對多與多對一的區別在於其關聯(relationship)的屬性在多的一方還是一的一方,如果relationship定義在一的一方那就是一對多.
1、一對一:
實際上將一對多加上條件 unique=True,就是一對一的外鍵
2、 一對多 Foreignkey:
1.構建外鍵。一個年級 對應多個學生。
這裏我們使用Student表 關聯到 Grade表
(1)Student關聯grade
添加外鍵id ----s_g-------》models.py—Student裏
列的類型要寫在鍵的前面;
鍵裏面的關聯要寫小寫引號 ;
默認的是 nullable;
class Student(db.Model):
s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(20), unique=True)
s_age = db.Column(db.Integer, default=8)
s_g = db.Column(db.Integer, db.ForeignKey('grade.g_id'), nullable=True) # 順序不能寫反, 先指定類型,再是外鍵
# 'grade.g_id'必須要小寫
__table__name = 'student'
def __init__(self, name, age): # 這裏的順序也很重要
self.s_name = name
self.s_age = age
(2)Grade關聯回Student
使用relationship
relationship裏的第一個參數是引號+類;
backref=‘stu’ 是反引時候的屬性
lazy: 懶惰算法,只有引用的時候才加載
class Grade(db.Model):
g_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
g_name = db.Column(db.String(10), unique=True)
g_desc = db.Column(db.String(100), nullable=True)
g_time = db.Column(db.Date, default=datetime.now())
students = db.relationship('Student', backref='stu', lazy=True)
__table__name = 'grade'
def __init__(self, name, desc):
self.g_name = name
self.g_desc = desc
(3)提交model
使用函數提交
提示:db.session.add() ---------db.session.commit()
(4)在創建外鍵之前提交過的話,使用下面的方法來進行外鍵關聯
使用原生sql語句
alter table student add constraint s_g foreign key(s_g) references Grade(g_id)
2.調用屬性查找
(1)通過grade 查找 student
直接調用relationship的實例化值
@grade.route('/selectstubygrade/<int:id>/')
def select_stu_by_grade(id):
grade = Grade.query.get(id)
stus = grade.students
return render_template('grade_Student.html', grade=grade, stus=stus)
(2)通過student 查找 grade
直接調用backref的值
@grade.route('/selectgradebystu/<int:id>/')
def select_grade_by_stu(id):
stus = Student.query.get(id)
grade = stus.stu
return render_template('select_stu_grade.html', grade=grade, stus=stus)
3、多對多
一個元素可以對應多個元素,多個元素中的一個也可以對應多個一個元素
比如:學生可以選擇多門課程, 每門課程有很多學生選課
1.構建外鍵
(1)配置class類
多對多需要第三張表,在flask中需要自己創建
a:配置第三張表
'student.s_id’中的student是表名
sc = db.Table('sc',
db.Column('s_id', db.Integer, db.ForeignKey('student.s_id'), primary_key=True),
db.Column('c_id', db.Integer, db.ForeignKey('course.c_id'), primary_key=True)
)
b: 關聯(例:課程)
'Student’是類名稱 , secondary是第三張表, backref是正向調用的名稱
class Course(db.Model):
c_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
c_name = db.Column(db.String(10), unique=True)
students = db.relationship('Student', secondary=sc, backref='cou')
# secondary是第三張表
def __init__(self, name):
self.c_name = name
2.使用
(1)student調用course:
Student.query.get(id).“backref”
@stu.route('/selectcoursebystu/<int:id>/')
def select_course_by_stu(id):
stu = Student.query.get(id)
cous = stu.cou
return render_template('stucourse.html', cous=cous, stu=stu)
(2)course調用student
Course.query.get(id).students
@stu.route('/selectstubycourse/<int:id>/')
def select_stu_by_course(id):
cou = Course.query.get(id)
stus = cou.students
return render_template('coursestu.html', stus=stus)
debug模式下的部分效果展示