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单例模式实例分析
Jan 14 Python
在Python中操作时间之tzset()方法的使用教程
May 22 Python
Python max内置函数详细介绍
Nov 17 Python
配置 Pycharm 默认 Test runner 的图文教程
Nov 30 Python
python解析xml简单示例
Jun 21 Python
Python列表对象实现原理详解
Jul 01 Python
基于python实现蓝牙通信代码实例
Nov 19 Python
.dcm格式文件软件读取及python处理详解
Jan 16 Python
解决TensorFlow GPU版出现OOM错误的问题
Feb 03 Python
使用python实现CGI环境搭建过程解析
Apr 28 Python
python在协程中增加任务实例操作
Feb 28 Python
如何使用Python对NetCDF数据做空间相关分析
Apr 21 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
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
PHP strcmp()和strcasecmp()的区别实例
2016/11/05 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
PHP实现用session来实现记录用户登陆信息
2018/10/15 PHP
PHP isset empty函数相关面试题及解析
2020/12/11 PHP
jqPlot Option配置对象详解
2009/07/25 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
编写针对IE的JS代码两种编写方法
2013/01/30 Javascript
artDialog双击会关闭对话框的修改过程分享
2013/08/05 Javascript
JavaScript模拟重力状态下抛物运动的方法
2015/03/03 Javascript
javascript下拉列表菜单的实现方法
2015/11/18 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
浅谈js中用$(#ID)来作为选择器的问题(id重复的时候)
2017/02/14 Javascript
javascript 中的try catch应用总结
2017/04/01 Javascript
微信小程序中上传图片并进行压缩的实现代码
2018/08/28 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
JS实现音乐钢琴特效
2020/01/06 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
2020/11/17 Vue.js
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
用生成器来改写直接返回列表的函数方法
2017/05/25 Python
使用Django实现把两个模型类的数据聚合在一起
2020/03/28 Python
python 对一幅灰度图像进行直方图均衡化
2020/10/27 Python
解决Pycharm 运行后没有输出的问题
2021/02/05 Python
使用CSS3和Checkbox实现JQuery的一些效果
2015/08/03 HTML / CSS
Vuori官网:运动服装的终级表现
2021/01/27 全球购物
农业局学习党的群众路线教育实践活动心得体会
2014/03/07 职场文书
党员廉洁自律承诺书
2014/05/26 职场文书
英语课前三分钟演讲稿
2014/08/19 职场文书
初中同学会活动方案
2014/08/22 职场文书
关于读书的演讲稿500字
2014/08/27 职场文书
2014年领班工作总结
2014/11/25 职场文书
故宫导游词
2015/01/31 职场文书
企业宣传语大全
2015/07/13 职场文书
利用Java设置Word文本框中的文字旋转方向的实现方法
2021/06/28 Java/Android