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实现web端用户登录和注册功能的教程
Apr 30 Python
python实现ping的方法
Jul 06 Python
Python基于pygame实现的font游戏字体(附源码)
Nov 11 Python
Python实现的简单dns查询功能示例
May 24 Python
Python处理命令行参数模块optpars用法实例分析
May 31 Python
python误差棒图errorbar()函数实例解析
Feb 11 Python
django 外键创建注意事项说明
May 20 Python
如何清空python的变量
Jul 05 Python
matplotlib图例legend语法及设置的方法
Jul 28 Python
PyQt5 QDockWidget控件应用详解
Aug 12 Python
简单了解Python字典copy与赋值的区别
Sep 16 Python
python 如何调用 dubbo 接口
Sep 24 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
DSP接收机前端设想
2021/03/02 无线电
PHP中使用strpos函数实现屏蔽敏感关键字功能
2014/08/21 PHP
Zend Framework创建自己的动作助手详解
2016/03/05 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
struts2 jquery 打造无限层次的树
2009/10/23 Javascript
js 页面关闭前的出现提示的实现代码
2011/05/25 Javascript
JavaScript实现复制功能各浏览器支持情况实测
2013/07/18 Javascript
用js来刷新当前页面保留参数的具体实现
2013/12/23 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
在JavaScript中操作时间之setYear()方法的使用
2015/06/12 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
2015/09/23 Javascript
深入理解jquery跨域请求方法
2016/05/18 Javascript
javascript小数精度丢失的完美解决方法
2016/05/31 Javascript
js重写方法的简单实现
2016/07/10 Javascript
AngularJS中如何使用echart插件示例详解
2016/10/26 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
详解Angular操作cookies方法
2018/06/01 Javascript
jQuery使用动画队列自定义动画操作示例
2018/06/16 jQuery
vue中动态设置meta标签和title标签的方法
2018/07/11 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
Python实现将不规范的英文名字首字母大写
2016/11/15 Python
pycharm安装图文教程
2017/05/02 Python
Python解析json时提示“string indices must be integers”问题解决方法
2019/07/31 Python
python opencv进行图像拼接
2020/03/27 Python
IE下实现类似CSS3 text-shadow文字阴影的几种方法
2011/05/11 HTML / CSS
超级搞笑检讨书
2014/01/15 职场文书
面试后的英文感谢信
2014/02/01 职场文书
俞敏洪励志演讲稿
2014/04/29 职场文书
我有一个梦想演讲稿
2014/05/05 职场文书
理想点亮人生演讲稿
2014/05/21 职场文书
优质服务口号
2014/06/11 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
不要在HTML中滥用div
2021/05/08 HTML / CSS
Python下载商品数据并连接数据库且保存数据
2022/03/31 Python
win11电脑关机鼠标灯还亮怎么解决? win11关机后鼠标灯还亮解决方法
2023/01/09 数码科技