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 28 Python
使用Python编写爬虫的基本模块及框架使用指南
Jan 20 Python
打包发布Python模块的方法详解
Sep 18 Python
win7上python2.7连接mysql数据库的方法
Jan 14 Python
python实现百万答题自动百度搜索答案
Jan 16 Python
朴素贝叶斯Python实例及解析
Nov 19 Python
python pexpect ssh 远程登录服务器的方法
Feb 14 Python
django基于restframework的CBV封装详解
Aug 08 Python
Python+OpenCV 实现图片无损旋转90°且无黑边
Dec 12 Python
利用OpenCV中对图像数据进行64F和8U转换的方式
Jun 03 Python
python matplotlib库的基本使用
Sep 23 Python
如何用Python和JS实现的Web SSH工具
Feb 23 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
fleaphp crud操作之find函数的使用方法
2011/04/23 PHP
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
2014/11/05 PHP
新浪微博OAuth认证和储存的主要过程详解
2015/03/27 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
php实现微信扫码自动登陆与注册功能
2016/09/22 PHP
推荐dojo学习笔记
2007/03/24 Javascript
jQuery移动和复制dom节点实用DOM操作案例
2012/12/17 Javascript
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
JS localStorage实现本地缓存的方法
2013/06/22 Javascript
eclipse如何忽略js文件报错(附图)
2013/10/30 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
JavaScript实现添加及删除事件的方法小结
2015/08/04 Javascript
EasyUI 结合JS导出Excel文件的实现方法
2016/11/10 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
2016/12/08 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
详解如何让Express支持async/await
2017/10/09 Javascript
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
vue.js input框之间赋值方法
2018/08/24 Javascript
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
2020/08/10 Javascript
Vue实现指令式动态追加小球动画组件的步骤
2020/12/18 Vue.js
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
简单了解python单例模式的几种写法
2019/07/01 Python
python读写csv文件方法详细总结
2019/07/05 Python
Python3从零开始搭建一个语音对话机器人的实现
2019/08/23 Python
python3 tcp的粘包现象和解决办法解析
2019/12/09 Python
Python实现动态给类和对象添加属性和方法操作示例
2020/02/29 Python
Pycharm连接远程服务器过程图解
2020/04/30 Python
饿了么订餐官网:外卖、网上订餐
2019/06/28 全球购物
《鸟岛》教学反思
2014/04/26 职场文书
大学生创业计划书
2014/08/14 职场文书
教师作风建设剖析材料
2014/10/11 职场文书
餐厅服务员岗位职责
2015/02/09 职场文书
2015年初中教务处工作总结
2015/07/21 职场文书