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对象类型及其运算方法(详解)
Jul 05 Python
Python3实现发送QQ邮件功能(文本)
Dec 15 Python
python实现海螺图片的方法示例
May 12 Python
django框架F&Q 聚合与分组操作示例
Dec 12 Python
Python continue语句实例用法
Feb 06 Python
python实现拼接图片
Mar 23 Python
Python转换字典成为对象,可以用"."方式访问对象属性实例
May 11 Python
浅析Python requests 模块
Oct 09 Python
python 爬取英雄联盟皮肤并下载的示例
Dec 04 Python
用python批量下载apk
Dec 29 Python
Python Matplotlib绘制动画的代码详解
May 30 Python
python基础之//、/与%的区别详解
Jun 10 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单件模式结合命令链模式使用说明
2008/09/07 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
Laravel源码解析之路由的使用和示例详解
2018/09/27 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
2020/07/08 PHP
解决 FireFox 下[使用event很麻烦] 的问题.
2006/08/22 Javascript
javaScript 简单验证代码(用户名,密码,邮箱)
2009/09/28 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
2010/03/02 Javascript
火狐下input焦点无法重复获取问题的解决方法
2014/06/16 Javascript
JavaScript中textRange对象使用方法小结
2015/03/24 Javascript
js基础知识(公有方法、私有方法、特权方法)
2015/11/06 Javascript
node.js使用cluster实现多进程
2016/03/17 Javascript
浅谈JavaScript中数组的增删改查
2016/06/20 Javascript
微信小程序 图片绝对定位(背景图片)
2017/04/05 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
Vue实现带进度条的文件拖动上传功能
2018/02/23 Javascript
Angular6新特性之Angular Material
2018/12/28 Javascript
浅析JS中NEW的实现原理及重写
2020/02/20 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
Python列表切片操作实例总结
2019/02/19 Python
Python基础教程之if判断,while循环,循环嵌套
2019/04/25 Python
20行python代码的入门级小游戏的详解
2019/05/05 Python
Python 计算任意两向量之间的夹角方法
2019/07/05 Python
把django中admin后台界面的英文修改为中文显示的方法
2019/07/26 Python
在Keras中利用np.random.shuffle()打乱数据集实例
2020/06/15 Python
Python机器学习工具scikit-learn的使用笔记
2021/01/28 Python
CSS3绘制六边形的简单实现
2016/08/25 HTML / CSS
英国排名第一的在线宠物用品商店:Monster Pet Supplies
2018/05/20 全球购物
逻辑链路控制协议
2016/10/01 面试题
传播学专业毕业生自荐信
2013/11/04 职场文书
毕业生找工作推荐信
2013/11/21 职场文书
写给保洁员表扬信
2014/01/08 职场文书
工伤事故赔偿协议书
2014/04/15 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
QT连接MYSQL数据库的详细步骤
2021/07/07 MySQL
Python+Pillow+Pytesseract实现验证码识别
2022/05/11 Python