flask的orm框架SQLAlchemy查询实现解析


Posted in Python onDecember 12, 2019

这篇文章主要介绍了flask的orm框架SQLAlchemy查询实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一对多,多对多是什么?

一对多。例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级。

多对多。例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生。

一对多查询

如果一个项目,有两张表。分别是班级表,学生表。

在设计数据表时,我们给学生表设置一个外键,指向班级表的 id 。

sqlalchemy 模板创建表的代码:

from flask import Flask, render_template, request, flash, redirect
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__,static_folder="static",template_folder="templates")

# 设置数据库连接属性
app.config['SQLALCHEMY_DATABASE_URI'] = '×××'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 实例化 ORM 操作对象
db = SQLAlchemy(app)

# 班级表
class Classes(db.Model):
  __tablename__ = "classes"
  id = db.Column(db.Integer,primary_key=True)
  name = db.Column(db.String(20),nullable=False,unique=True)

# 学生表
class Students(db.Model):
  __tablename__ = "students"
  id = db.Column(db.Integer,primary_key=True)
  name = db.Column(db.String(40),nullable=False)
  cls_id = db.Column(db.Integer,db.ForeignKey("classes.id"))  # 注意要写成(表名.字段名)

创建完表,插入完数据后。

如果我们知道学生的学号,要查学生班级的名称,应该怎么操作呢?

现在可以用一种比较麻烦的方达查询:

cls_id = Students.query.filter(Student.id == 'xxx').first()
cls = Classes.query.filter(Classes.id == cls.id).first()
print(cls.name)

这样的方法太麻烦了,有没有简单的办法?

上面创建表的代码,在18行可以插入一条语句。

relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')

其中realtionship描述了Students和Classes的关系。在此文中,第一个参数为对应参照的类"Students"

第二个参数backref为类Students申明新属性的方法

第三个参数lazy决定了什么时候SQLALchemy从数据库中加载数据

如果设置为子查询方式(subquery),则会在加载完Classes对象后,就立即加载与其关联的对象,这样会让总查询数量减少,但如果返回的条目数量很多,就会比较慢

另外,也可以设置为动态方式(dynamic),这样关联对象会在被使用的时候再进行加载,并且在返回前进行过滤,如果返回的对象数很多,或者未来会变得很多,那最好采用这种方式
如果一大堆理论看不明白,那么知道怎么用就可以了。

如果知道学生的姓名,想知道班级的名称,可以这样查:

stu = Students.query.filter(Students.name == 'xxx').first()
stu.relate_class.name # stu.relate_class 会跳到 classes 表

如果知道班级的名称,想返回全部学生的名字的列表,可以这样查:

cls = Classes.query.filter(Classes.name == 'xxx').first()
cls.relate_student.name # cls.relate_stu 会跳到 students 表

可以使用这样的方法,有两个要求,第一是要设置外键,第二是这句语句:

relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')

注意,什么时候用 relate_student ,什么时候用 relate_class 。以及 relationship 这条语句的书写,要清楚!

多对多查询

假设一堆学生选了不同的课程,这就是多对多关系。

tb_student_course = db.Table('tb_student_course',
               db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
               db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))
               )


class Student(db.Model):
  __tablename__ = "students"
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(64), unique=True)
 # 关联属性,多对多的情况,可以写在任意一个模型类中
  relate_courses = db.relationship('Course', secondary=tb_student_course,
               backref='relate_student',
               lazy='dynamic')

class Course(db.Model):
  __tablename__ = "courses"
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(64), unique=True)

添加测试数据:

# 添加测试数据

  stu1 = Student(name='张三')
  stu2 = Student(name='李四')
  stu3 = Student(name='王五')

  cou1 = Course(name='物理')
  cou2 = Course(name='化学')
  cou3 = Course(name='生物')

  stu1.courses = [cou2, cou3]  # 记得要添加关系
  stu2.courses = [cou2]
  stu3.courses = [cou1, cou2, cou3]

  db.session.add_all([stu1, stu2, stu2])
  db.session.add_all([cou1, cou2, cou3])

  db.session.commit()

要查某个学生修的全部课程,修了某个课程的全部学生:

for course in stu1.relate_courses:
  print(course.name)
for student in cou2.relate_student:
  print(student)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的fileinput模块的简单实用示例
Jul 09 Python
Python实现的特征提取操作示例
Dec 03 Python
Python基于滑动平均思想实现缺失数据填充的方法
Feb 21 Python
使用PyQt4 设置TextEdit背景的方法
Jun 14 Python
详解python中的生成器、迭代器、闭包、装饰器
Aug 22 Python
python统计指定目录内文件的代码行数
Sep 19 Python
python的slice notation的特殊用法详解
Dec 27 Python
OpenCV python sklearn随机超参数搜索的实现
Jan 17 Python
使用Python操作MySQL的小技巧
Sep 10 Python
python自动从arxiv下载paper的示例代码
Dec 05 Python
Python中快速掌握Data Frame的常用操作
Mar 31 Python
Python3.8官网文档之类的基础语法阅读
Sep 04 Python
python实现批量处理将图片粘贴到另一张图片上并保存
Dec 12 #Python
Python FtpLib模块应用操作详解
Dec 12 #Python
Python PyInstaller库基本使用方法分析
Dec 12 #Python
Python + Requests + Unittest接口自动化测试实例分析
Dec 12 #Python
python opencv图片编码为h264文件的实例
Dec 12 #Python
Python pygame绘制文字制作滚动文字过程解析
Dec 12 #Python
详解python 中in 的 用法
Dec 12 #Python
You might like
无线电波是什么?它是怎样传输的?
2021/03/01 无线电
在PHP语言中使用JSON和将json还原成数组的方法
2016/07/19 PHP
不一样的文字闪烁 轮番闪烁
2009/11/11 Javascript
js 操作select与option(示例讲解)
2013/12/20 Javascript
jquery控制select的text/value值为选中状态
2014/06/03 Javascript
jquery实现表单输入时提示文字滑动向上效果
2015/08/10 Javascript
JavaScript实现简单获取当前网页网址的方法
2015/11/09 Javascript
bootstrap-treeview自定义双击事件实现方法
2016/01/09 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
微信小程序 PHP后端form表单提交实例详解
2017/01/12 Javascript
jQuery居中元素scrollleft计算方法示例
2017/01/16 Javascript
详解JavaScript中js对象与JSON格式字符串的相互转换
2017/02/14 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
JS严格模式知识点总结
2018/02/27 Javascript
详解Angularjs 自定义指令中的数据绑定
2018/07/19 Javascript
微信小程序使用Vant Weapp组件库的方法步骤
2019/08/01 Javascript
如何基于JavaScript判断图片是否加载完成
2019/12/28 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
[43:32]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第一场
2014/05/26 DOTA
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
2020/04/03 Python
解决Python发送Http请求时,中文乱码的问题
2020/04/30 Python
python 实现单例模式的5种方法
2020/09/23 Python
移动HTML5前端框架—MUI的使用
2017/12/18 HTML / CSS
Farfetch澳大利亚官网:Farfetch Australia
2020/04/26 全球购物
请写出一段Python代码实现删除一个list里面的重复元素
2015/12/29 面试题
大三自我鉴定范文
2013/10/05 职场文书
税务专业毕业生自荐信
2013/11/10 职场文书
应用艺术毕业生的自我评价
2013/12/04 职场文书
元旦联欢会主持词
2014/03/26 职场文书
学生乘坐校车安全责任书
2015/05/11 职场文书
2015年办税服务厅工作总结
2015/07/23 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书
opencv 分类白天与夜景视频的方法
2021/06/05 Python