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中datetime常用时间处理方法
Jun 15 Python
举例详解Python中yield生成器的用法
Aug 05 Python
Python实现的选择排序算法示例
Nov 29 Python
python with提前退出遇到的坑与解决方案
Jan 05 Python
python3实现多线程聊天室
Dec 12 Python
Python 利用pydub库操作音频文件的方法
Jan 09 Python
Python 进程操作之进程间通过队列共享数据,队列Queue简单示例
Oct 11 Python
CentOS7下安装python3.6.8的教程详解
Jan 03 Python
PyTorch加载预训练模型实例(pretrained)
Jan 17 Python
python实现随机加减法生成器
Feb 24 Python
python matplotlib实现将图例放在图外
Apr 17 Python
Django中的AutoField字段使用
May 18 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中include()与require()的区别说明
2017/02/14 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
UserData用法总结 lanyu出品
2010/07/01 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
如何用JavaScript定义一个类
2014/09/12 Javascript
JavaScript自定义等待wait函数实例分析
2015/03/23 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
JavaScript利用HTML DOM进行文档操作的方法
2016/03/28 Javascript
值得分享的Bootstrap Table使用教程
2016/11/23 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
使用npm安装最新版本nodejs
2018/01/18 NodeJs
Vue 实现树形视图数据功能
2018/05/07 Javascript
浅谈微信小程序flex布局基础
2018/09/10 Javascript
又拍云 Node.js 实现文件上传、删除功能
2018/10/28 Javascript
vue+Element-ui实现分页效果实例代码详解
2018/12/10 Javascript
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python做简单的字符串匹配详解
2017/03/21 Python
Python操作json的方法实例分析
2018/12/06 Python
对Django中static(静态)文件详解以及{% static %}标签的使用方法
2019/07/28 Python
Python实现名片管理系统
2020/02/14 Python
python使用Geany编辑器配置方法
2020/02/21 Python
浅谈Python程序的错误:变量未定义
2020/06/02 Python
杭州SQL浙江浙大网新恩普软件有限公司
2013/07/27 面试题
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/01/13 面试题
百度软件工程师职位
2013/02/14 面试题
学院书画协会部门岗位职责
2013/12/01 职场文书
四年级数学教学反思
2014/02/02 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
企业活动策划方案
2014/06/02 职场文书
政府法律服务方案
2014/06/14 职场文书
运动员获奖感言
2014/08/15 职场文书
房屋出租协议书范本(标准版)
2014/09/24 职场文书
党员干部四风问题整改措施思想汇报
2014/10/12 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
网络研修心得体会
2016/01/08 职场文书
导游词之徐州-云龙山
2019/09/29 职场文书