#encoding=utf-8 """ 1、常用关键词 (1)反向映射:db.relationship() A、relationship:单纯表现两表模型之间的关系,便于一对多查询过程 B、backref:用于通过多表操作一表的数据 C、uselist=False:指定只能查询到一个(一对一中使用) D、可以根据映射的名字将数据添加到另一个表中;根据反向字段将他表的数据添加到本表中 E、可以通过映射的名字获取到另一个表的信息,通过反向字段获取到本表的信息 (2)外键字段:db.Column(db.Integer,db.ForeignKey("表名小写.id")) A、外键,就是在一对多关系当中,在多表当中搭建字段,指向一表的id形成关联关系 B、一般存储的是Integer整型字段 C、一般用于通过多表操作一表的数据 2、一对多关系:采用外键 (1)一对多表的创建:一个职位多个员工,一个员工一个职位,职位是一表,员工是多表 A、一表中创建多表的反向映射:db.relationship("多表名",backref = "映射字段名") B、多表中创建一表的外键字段:db.Column(db.Integer,db.ForeignKey("一表名.id")) (2)增加数据(先一表,后多表) A、一表增加数据:常规添加(反向映射字段不增加) pos = Position() pos.pos_name = '普通职员' pos.save() B、多表增加数据 >> 可以自定义关联一表已存在的id per = Person() per.per_name = '李四' per.per_position=1 per.save() >> 可以先查询一表数据再查询id进行增加 # 多表再增加数据(手动定义) per = Person() per.per_name = '李四' per.per_position = 1 per.save() # 多表再增加数据(查询增加) position = Position.query.filter_by(pos_name="vip职员").first() per = Person() per.per_name = '李四' per.per_position = position.id per.save() C、一添多 u1 = User.query.get(1) u2 = User.query.get(2) role = Role.query.get(1) role.r_user = [u1,u2] role.save() D、多添加一:要注意映射字段,和映射数据 u = User.query.get(3) u.u_role = 10 u.save() E、添加关联外键 Role:r_user = db.relationship("User",backref="user_role") u = User.query.get(3) u.u_role = Role.query.get(5) u.save() F、一查询多 role = Role.query.get(1) user = role.r_user G、多查询一 user = User.query.get(2) role = user.u_role (3)查询数据 A、一表查询多表:通过多表查询全部信息,全部信息.反向映射.一表信息 B、多表查询一表:通过一表查询全部信息,循环全部信息.反向映射表名称,单次循环.多表信息 3、一对一关系:相对多对一,在外键映射中添加uselist=False (1)一对一表的创建:一个丈夫一名妻子 A、一表中创建一表的反向映射:db.relationship("多表名",backref = "映射字段名",uselist=False) B、一表中创建一表的外键字段:db.Column(db.Integer,db.ForeignKey("一表名.id")) (2)增加数据(先映射,后外键) A、一表增加数据:常规添加(反向映射字段不增加) pos = Position() pos.pos_name = '普通职员' pos.save() B、多表增加数据 >> 可以自定义关联一表已存在的id per = Person() per.per_name = '李四' per.per_position=1 per.save() >> 可以先查询一表数据再查询id进行增加 # 多表再增加数据(手动定义) per = Person() per.per_name = '李四' per.per_position = 1 per.save() # 多表再增加数据(查询增加) position = Position.query.filter_by(pos_name="vip职员").first() per = Person() per.per_name = '李四' per.per_position = position.id per.save() (3)查询数据 A、一表查询多表:通过多表查询全部信息,全部信息.反向映射.一表信息 B、多表查询一表:通过一表查询全部信息,循环全部信息.反向映射表名称,单次循环.多表信息 4、多对多关系:采用中间表 (1)数据库多对多关系,可以使用中间表,中间表由中间表的名称、一表的外键、另一表的外键组成 职位和权限:一个职位可以有多种权限,一种权限可以给多个职位 (2)中间表实例:中间表表名=db.Table(中间表表名,关联课程外键,关联学生外键) (3)其中一个表:反向映射名=db.relationship(另一个表的类名,secondary=中间表的名称,backref=反向映射字段) (4)另一个表正常创建 (5)可以根据反向映射的反向字段,向另一表增加数据:x.student_c = c (6)可以根据反向映射的名字,向所在的表添加数据:c.c_student = x (7)可以根据反向映射的名字,从所在表查询另一表信息:s_lst=[s for s in c.c_student] (8)可以根据反向映射的反向字段,从另一表查询本表的信息:c_lst = [c for c in s.student_c] A、给用户添加课程 c1 = Course.query.get(1) c2 = Course.query.get(2) user = User.query.get(1) user.u_course = [c1,c2] user.save() B、给课程添加用户 u1 = User.query.get(1) u2 = User.query.get(2) course = Course.query.get(1) course.c_user = [u1,u2] course.save() C、查询指定用户所有的课程 user = User.query.get(1) course = user.u_course D、查询指定课程的所有用户 course = Course.query.get(1) user = course.c_user """ from flask import Flask from flask_sqlalchemy import SQLAlchemy from BluePro.models import BaseModel basic = "F:\\MyProject\\027_Flask框架介绍\\BluePro" # 创建web服务器(http)实例:内置方法__name__是预定义变量,被设置为使用本模块,html存放的路径,静态文件的路径 app = Flask(__name__) # 设置数据库配置 # 配置创建sqlite数据库文件 app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{basic}/database2.sqlite" # 配置数据库动态跟踪修改 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True # 实例化SQLAlchemy db = SQLAlchemy(app) # 一表:职位表 class Position(BaseModel): pos_name = db.Column(db.String(32)) pos_per = db.relationship("Person",backref="person_position") # 多表:职员表 class Person(BaseModel): per_name = db.Column(db.String(32)) per_position = db.Column(db.Integer, db.ForeignKey("position.id")) # 一表:丈夫表 class Husband(BaseModel): h_name = db.Column(db.String(32)) h_wife = db.relationship("Wife",backref="wife_husband",uselist=False) # 一表:妻子表 class Wife(BaseModel): w_name = db.Column(db.String(32)) w_husband = db.Column(db.Integer, db.ForeignKey("husband.id")) # 中间表:学生+学科表 stu_sub = db.Table( # 中间表的名称 "stu_sub", # 学生表的外键 db.Column("student_id",db.Integer, db.ForeignKey("student.id")), # 学科表的外键 db.Column("subject_id",db.Integer, db.ForeignKey("subject.id")), ) # 多表:学生表 class Student(BaseModel): s_name = db.Column(db.String(32), unique=True) # 学生-学科 多对多:外面创建中间表,任一表创建外键映射表 s_sub = db.relationship( # 映射表 "Subject", # 中间表 secondary=stu_sub, # 反向映射 backref="sub_stu" ) # 多表:学科表 class Subject(BaseModel): sub_name = db.Column(db.String(32)) # 创建数据表 @app.route('/database/create/') def create(): db.create_all() return "创建完毕" # 一对多增加数据 @app.route('/database/OneToManyAdd/') def OneToManyAdd(): # 一表先增加数据 pos = Position() pos.pos_name = '普通职员' pos.save() pos = Position() pos.pos_name = 'vip职员' pos.save() # 多表再增加数据(手动定义) per = Person() per.per_name = '李四' per.per_position = 1 per.save() # 多表再增加数据(查询增加) position = Position.query.filter_by(pos_name="vip职员").first() per = Person() per.per_name = '王五' per.per_position = position.id per.save() return "添加完毕" # 一对多查询数据 @app.route('/database/OneToManySelect/') def OneToManySelect(): # 一表查询多表数据:relationship正向(关系字段),可以查询到多个 position = Position.query.get(1) person = [per.per_name for per in position.pos_per] print(person) # 多表查询一表数据:relationship反向(反向映射名称),只会对应一个 person = Person.query.get(1) print(person.person_position.pos_name) return "查询完毕" # 一对多查询数据 @app.route('/database/OneToManySelectAdd/') def OneToManySelectAdd(): # 一表查询多表数据,赋值增加 position = Position.query.get(2) per1 = Person(per_name="增加1") per2 = Person(per_name="增加2") per1.save() per2.save() position.pos_per = [per1,per2] position.save() return "出现问题:所有对应职位的数据都被清除,重新给予" # 一对一增加数据 @app.route('/database/OneToOneAdd/') def OneToOneAdd(): # 一表(映射字段)先增加数据 h = Husband() h.h_name = '张三' h.save() h = Husband() h.h_name = '李四' h.save() # 一表(外键字段)再增加数据(手动定义) w = Wife() w.w_name = '0001' w.w_husband = 1 w.save() # 多表再增加数据(查询增加) husband = Husband.query.filter_by(h_name="李四").first() w = Wife() w.w_name = '0002' w.w_husband = husband.id w.save() return "添加完毕" # 一对一查询数据 @app.route('/database/OneToOneSelect/') def OneToOneSelect(): # 一表(关系)查询多表(外键)数据:关系字段 husband = Husband.query.get(1) print(husband.h_wife.w_name) # 多表查询一表数据:反向映射名称,只会对应一个 wife = Wife.query.get(1) print(wife.wife_husband.h_name) return "查询完毕" # 多对多增加数据 @app.route('/database/ManyToManyAdd/') def ManyToManyAdd(): # 两张普通表增加数据 for m in ["数学", "语文", "英语", "Python", "Java"]: sub = Subject() sub.sub_name = m sub.save() for n in "昆晏香雷松莲灵晓艺瑗": s = Student() s.s_name = "赵" + n s.save() # 中间表增加数据 # # 通过普通表增加数据 # subject = Subject.query.all() # for sub in subject: # sub.sub_stu = [s for s in Student.query.all()] # sub.save() # # 通过关系表增加数据 # student = Student.query.all() # for stu in student: # stu.s_sub = [s for s in Subject.query.all()] # stu.save() return "添加完毕" # 多对多 查询 @app.route('/database/ManyToManySelect/') def ManyToManySelect(): # 常规查询映射 subject = Subject.query.get(1) student = [s.s_name for s in subject.sub_stu] print(student) # 映射查询常规 student = Student.query.get(2) subject = [sub.sub_name for sub in student.s_sub] print(subject) return "查询完毕" # 多对多 查询 增加 @app.route('/database/ManyToManySelectAdd/') def ManyToManySelectAdd(): # 常规查询映射 赋值 stu1 = Student.query.get(1) stu2 = Student.query.get(2) subject = Subject.query.get(1) subject.sub_stu = [stu1,stu2] subject.save() # 常规查询映射 追加 stu3 = Student.query.get(3) subject = Subject.query.get(1) subject.sub_stu.append(stu3) subject.save() # 映射查询常规 赋值 sub1 = Subject.query.get(3) sub2 = Subject.query.get(4) student = Student.query.get(5) student.s_sub = [sub1,sub2] student.save() # 映射查询常规 追加 sub3 = Subject.query.get(5) student = Student.query.get(5) student.s_sub.append(sub3) student.save() return "玩不" # 启动项目服务器--可以通过参数更改,通常网站的页面需要放到网站服务器上,用户无法双击打开 if __name__ == '__main__': app.run( # host:主机地址 host="localhost", # port:访问端口 port=80, # debug:调试模式,测试环境True,生产环境Fasle debug=True, # use_reloader:自动重启 use_reloader=True )
Flask06_ORM多表
最新推荐文章于 2024-03-14 12:21:14 发布