python-web flask 關於models

一、關於級聯刪除

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模式下的部分效果展示
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章