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实现list元素按关键字相加减的方法示例
Jun 09 Python
Python构建XML树结构的方法示例
Jun 30 Python
Django 如何获取前端发送的头文件详解(推荐)
Aug 15 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
Aug 22 Python
python实现机器学习之多元线性回归
Sep 06 Python
python中web框架的自定义创建
Sep 08 Python
Python多线程爬取豆瓣影评API接口
Oct 22 Python
Python计算不规则图形面积算法实现解析
Nov 22 Python
Pytorch实现LSTM和GRU示例
Jan 14 Python
python怎么删除缓存文件
Jul 19 Python
M1芯片安装python3.9.1的实现
Feb 02 Python
Windows安装Anaconda3的方法及使用过程详解
Jun 11 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 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
php的memcache类分享(memcache队列)
2014/03/26 PHP
php实现模拟post请求用法实例
2015/07/11 PHP
php实现图片以base64显示的方法
2016/10/13 PHP
JS获取月份最后天数、最大天数与某日周数的方法
2015/12/08 Javascript
html5+javascript实现简单上传的注意细节
2016/04/18 Javascript
原生js编写2048小游戏
2017/03/17 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
bmob js-sdk 在vue中的使用教程
2018/01/21 Javascript
3种vue路由传参的基本模式
2018/02/22 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
[02:43]中国五虎出征TI3视频
2013/08/02 DOTA
[01:09]模型精美,特效酷炫!TI9不朽宝藏Ⅰ鉴赏
2019/05/10 DOTA
使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)
2014/04/25 Python
详解Django中的form库的使用
2015/07/18 Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
2015/11/05 Python
总结用Pdb库调试Python的方式及常用的命令
2016/08/18 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
如何用Python合并lmdb文件
2018/07/02 Python
Dlib+OpenCV深度学习人脸识别的方法示例
2019/05/14 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
2019/05/27 Python
python爬虫利用代理池更换IP的方法步骤
2021/02/21 Python
纯HTML5+CSS3制作图片旋转
2016/01/12 HTML / CSS
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
英国第二大营养品供应商:Vitabiotics
2016/10/01 全球购物
Corelle官方网站:购买康宁餐具
2016/11/02 全球购物
澳大利亚有机化妆品网上商店:The Well Store
2020/02/20 全球购物
中国好声音华少广告词
2014/03/17 职场文书
经管应届生求职信范文
2014/05/18 职场文书
社区爱国卫生月活动总结
2014/06/30 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
python 提取html文本的方法
2021/05/20 Python
一条慢SQL语句引发的改造之路
2022/03/16 MySQL
在Centos 8.0中安装Redis服务器的教程详解
2022/03/21 Redis