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制作简单的朴素基数估计器的教程
Apr 01 Python
Python删除windows垃圾文件的方法
Jul 14 Python
Python的迭代器和生成器
Jul 29 Python
Java多线程编程中ThreadLocal类的用法及深入
Jun 21 Python
python利用paramiko连接远程服务器执行命令的方法
Oct 16 Python
python读取txt文件并取其某一列数据的示例
Feb 19 Python
python opencv捕获摄像头并显示内容的实现
Jul 11 Python
Python字典的概念及常见应用实例详解
Oct 30 Python
python 循环数据赋值实例
Dec 02 Python
解决python运行效率不高的问题
Jul 20 Python
Python如何定义接口和抽象类
Jul 28 Python
20行代码教你用python给证件照换底色的方法示例
Feb 05 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
php数组一对一替换实现代码
2012/08/31 PHP
php实现等比例不失真缩放上传图片的方法
2016/11/14 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
2017/05/05 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
firefox下input type="file"的size是多大
2011/10/24 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
jquery 单引号和双引号的区别及使用注意
2013/07/31 Javascript
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
2013/08/15 Javascript
js获取checkbox值的方法
2015/01/28 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
2020/04/20 Javascript
详解JavaScript中数组和字符串的lastIndexOf()方法使用
2016/03/13 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
详解vuejs之v-for列表渲染
2017/06/22 Javascript
JavaScript代码实现txt文件的上传预览功能
2018/03/27 Javascript
Vue组件之极简的地址选择器的实现
2018/05/31 Javascript
浅谈vue方法内的方法使用this的问题
2018/09/15 Javascript
JavaScript刷新页面的几种方法总结
2019/03/28 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
微信小程序进入广告实现代码实例
2019/09/19 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
jQuery-App输入框实现实时搜索
2020/11/19 jQuery
详解Vue的异步更新实现原理
2020/12/22 Vue.js
JavaScript 中的六种循环方法
2021/01/06 Javascript
python使用socket向客户端发送数据的方法
2015/04/29 Python
Python实现希尔排序算法的原理与用法实例分析
2017/11/23 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
浅谈python3打包与拆包在函数的应用详解
2020/05/02 Python
python tkinter实现连连看游戏
2020/11/16 Python
历史专业毕业生的自我鉴定
2013/11/15 职场文书
我为自己代言广告词
2014/03/18 职场文书
2014年文明创建工作总结
2014/11/25 职场文书
七年级语文教学反思
2016/03/03 职场文书
Python基础详解之描述符
2021/04/28 Python
pytorch 实现多个Dataloader同时训练
2021/05/29 Python
postgresql如何找到表中重复数据的行并删除
2023/05/08 MySQL