Python Web 之 Flask SQLalchemy

Flask-SQLalchemy

一、 一对多

A表中的一条记录与B表中的多天记录关联

语法实现:

  • 在“多”实体类中增加

    外键列名 = db.Column(db.Integer, db.ForeignKey(主表.主键))

  • 在“一”实体中增加反向引用关系

    属性名=db.creationship("多的实体类名", 关系选项, lazy="dynamic")

    属性名=db.creationship("多的实体类名", backref="属性名", lazy="dynamic")

选项名 说明
backref 在关系的另一个模型中添加反向引用
lazy 指定如何加载相关记录(select:首次加载时访问;immediate:源对象加载之后马上就加载关联数据;subquery:立即加载,但是使用子查询;noload:永不加载;dynamic:不加载记录,单提供加载记录的查询)
·selist 如果设置为True,则不适用列表,使用标量
secondary 指定多堆垛关系中关联表的名字

新建两张表,分别是teacher和course,使用外键course_id和course表中的id关联

teacher为一、course为多

1. 建表

class Teacher(db.Model):
    __tablename_ = "teacher"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    tname = db.Column(db.String(30), nullable=False)
    tage = db.Column(db.Integer)

    #增加一列,引用主键的id,外键列,引用主键表(course)的主键列
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'))

    def __init__(self, tname, tage):
        self.tname = tname
        self.tage = tage

    def __repr__(self):
        return "<Teacher: 教师姓名(%r) 年龄(%r)>"%(self.tname, self.tage)

class Course(db.Model):
    __tablename__ = "course"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    cname = db.Column(db.String(30), nullable=False)

    # 反向引用:返回与当前课程相关的teacher列表
    #backref :定义反向关系,本质上回向teacher的实体中增加一个course属性,该属性可替代curse_id来访问Course,此时获得到的是模型对象,而不是外键值
    teachers = db.relationship("Teacher", backref='course', lazy="dynamic")

    def __init__(self, cname):
        self.cname = cname

    def __repr__(self):
        return "<Course: 课程名(%r)>"%self.cname

2. 增加数据

法一

teacher = Teacher("苍老师", 37)
teacher.course_id = 1
db.session.add(teacher)

法二:根据course_id查询出一个Course实体,再将Course实体赋值给teacher

    teacher = Teacher("苍老师", 37)
    course = Course.query.filter_by(id=1).first()
    teacher.course = course
    db.session.add(teacher)

3. 查询数据

法一(多查一)

    # 双向查询,通过course查teacher,通过teacher查course
    #通过course查询所有的teacher
    course = Course.query.filter_by(id=1).first()
    #根据course对象查询所由的teacher对象
    teachers = course.teachers.all()
    print(teachers)

法二(一查多)

teacher = Teacher.query.filter_by(tname="波老师").first()
course = teacher.course
print("教师:%s , 课程:%s"%(teacher.tname, course.cname))

发三(原生查询)

results = db.session.query(Teacher, Course).filter(Teacher.course_id == Course.id).all()
for result in results:
    print(result.Teacher.tname, result.Course.cname)

二、 一对一

A表中的一条记录只能与B表中的一条记录关联

B表中的一条记录只能与A表中的一条记录关联

1. 语法

2. 建表

class Man(db.Model):
    __tablename__ = "man"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    mname = db.Column(db.String(30))
    mage = db.Column(db.Integer)

    #增加反向引用,与Woman实体类一对一引用允许在Man中得到一个Woman的信息,同时,在Woman中也能得到一个man信息
    woman = db.relationship("Woman", backref="man", uselist=False)

    def __init__(self, mname, mage):
        self.mname = mname
        self.mage = mage

    def __repr__(self):
        return "<Man:%r %r>"%(self.mname, self.mage)

class Woman(db.Model):
    __tablename__ = "woman"
    id = db.Column(db.Integer, primary_key=True)
    wname = db.Column(db.String(30))
    wage = db.Column(db.Integer)

    #增加一个列,表示引用自man表的主键
    man_id = db.Column(db.Integer, db.ForeignKey("man.id"))

    def __init__(self, wname, wage):
        self.wname = wname
        self.wage = wage

    def __repr__(self):
        return "<Woman:%r %r>"%(self.wname, self.wage)

3. 插入

#查询王老师信息
wang = Man.query.filter_by(mname="王老师").first()
#创建wife对象
wife = Woman("王夫人", 16)
#将王老师对象赋值给wife
wife.man = wang
#将wife保存
db.session.add(wife)
return "OK"

4. 查询

#通过man找woman
man = Man.query.filter_by(mname="王老师").first()
woman = man.woman
print(man.mname, woman.wname)
return "OK"

#通过woman找man
wife = Woman.query.filter_by(wname="王夫人").first()
man = wife.man
print(wife.wname, man.mname)

三、多对多

1. 实现

增加关联属性以及反向引用

course=db.relationship("course", secondary="student_course", lazy="dynamic", backref=db.backref("student", lazy="dynamic"))

posted @ 2019-09-03 09:00  ChanceySolo  阅读(231)  评论(0编辑  收藏  举报