摘要
外键的形式有一对一, 一对多, 多对多
一、一对一
实际上将一对多加上条件 unique=True,就是一对一的外键
二、一对多 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)
三、多对多
一个元素可以对应多个元素,多个元素中的一个也可以对应多个一个元素
比如:学生可以选择多门课程, 每门课程有很多学生选课
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')
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模式下的部分效果展示