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中mechanize库的简单使用示例
Jan 10 Python
python实现的守护进程(Daemon)用法实例
Jun 02 Python
Python中super()函数简介及用法分享
Jul 11 Python
Python升级导致yum、pip报错的解决方法
Sep 06 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
详解利用OpenCV提取图像中的矩形区域(PPT屏幕等)
Jul 01 Python
Django Rest framework频率原理与限制
Jul 26 Python
python wxpython 实现界面跳转功能
Dec 17 Python
pycharm 2018 激活码及破解补丁激活方式
Sep 21 Python
Python键鼠操作自动化库PyAutoGUI简介(小结)
May 17 Python
Python3爬虫中关于Ajax分析方法的总结
Jul 10 Python
python 三边测量定位的实现代码
Apr 22 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
Add a Table to a Word Document
2007/06/15 Javascript
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
基于jQuery的js分页代码
2010/06/10 Javascript
IE6、IE7中setAttribute不支持class/for/rowspan/colspan等属性
2011/08/28 Javascript
js当一个变量为函数时 应该注意的一点细节小结
2011/12/29 Javascript
说说JSON和JSONP 也许你会豁然开朗
2012/09/02 Javascript
jquery滚动组件(vticker.js)实现页面动态数据的滚动效果
2013/07/03 Javascript
Js nodeType 属性全面解析
2013/11/14 Javascript
当jQuery1.7遇上focus方法的问题
2014/01/26 Javascript
js函数参数设置默认值的一种变通实现方法
2014/05/26 Javascript
JQuery做的一个简单的点灯游戏分享
2014/07/16 Javascript
javascript中FOREACH数组方法使用示例
2016/03/01 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
微信小程序页面滑动屏幕加载数据效果
2020/11/16 Javascript
vue axios同步请求解决方案
2017/09/29 Javascript
Node中使用ES6语法的基础教程
2018/01/05 Javascript
VSCode中如何利用d.ts文件进行js智能提示
2018/04/13 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
Angular刷新当前页面的实现方法
2018/11/21 Javascript
小试SVG之新手小白入门教程
2019/01/08 Javascript
Bootstrap实现省市区三级联动(亲测可用)
2019/07/26 Javascript
JavaScript实现4位随机验证码的生成
2021/01/28 Javascript
[02:36]DOTA2英雄基础教程 帕格纳
2014/01/20 DOTA
python 自动批量打开网页的示例
2019/02/21 Python
python编写微信公众号首图思路详解
2019/12/13 Python
css3遮罩层镂空效果的多种实现方法
2020/05/11 HTML / CSS
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
英国莱斯特松木橡木家具网上商店:Choice Furniture Superstore
2019/07/05 全球购物
TOWER London官网:鞋子、靴子、运动鞋等
2019/07/14 全球购物
工作表扬信的范文
2014/01/10 职场文书
学习雷锋精神演讲稿
2014/05/10 职场文书
乳制品整治工作方案
2014/05/29 职场文书
技术入股合作协议书
2016/03/21 职场文书
vue ref如何获取子组件属性值
2022/03/31 Vue.js