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实现将汉字转换成汉语拼音的库
May 05 Python
python通过get,post方式发送http请求和接收http响应的方法
May 26 Python
Python scikit-learn 做线性回归的示例代码
Nov 01 Python
python调用Delphi写的Dll代码示例
Dec 05 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
python使用matplotlib模块绘制多条折线图、散点图
Apr 26 Python
Python3中在Anaconda环境下安装basemap包
Oct 21 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
Dec 05 Python
python3字符串操作总结
Jul 24 Python
安装完Python包然后找不到模块的解决步骤
Feb 13 Python
Python中使用socks5设置全局代理的方法示例
Apr 15 Python
详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
Jan 29 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中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
2013/02/14 PHP
php将文本文件转换csv输出的方法
2014/12/31 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
PHP strcmp()和strcasecmp()的区别实例
2016/11/05 PHP
PHP7下协程的实现方法详解
2017/12/17 PHP
php连接mysql之mysql_connect()与mysqli_connect()的区别
2020/07/19 PHP
javascript中对对层的控制
2006/12/29 Javascript
jQuery中文入门指南,翻译加实例,jQuery的起点教程
2007/02/09 Javascript
javascript 打印内容方法小结
2009/11/04 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
JavaScript自执行闭包的小例子
2013/06/29 Javascript
js保留小数点后几位的写法
2014/01/03 Javascript
脚本合并提升javascript性能示例
2014/02/24 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
实现图片预加载的三大方法及优缺点分析
2014/11/19 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
jquery获取节点名称
2015/04/26 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
简单实现的JQuery文本框水印插件
2016/06/14 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
vue相同路由跳转强制刷新该路由组件操作
2020/08/05 Javascript
[52:29]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第三局
2016/03/03 DOTA
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
python解决字符串倒序输出的问题
2018/06/25 Python
Django restframework 源码分析之认证详解
2019/02/22 Python
使用Python代码实现Linux中的ls遍历目录命令的实例代码
2019/09/07 Python
给大家整理了19个pythonic的编程习惯(小结)
2019/09/25 Python
世界上最大的二手相机店:KEN
2017/05/17 全球购物
广告设计应届生求职信
2014/03/01 职场文书
2014年公司庆元旦活动方案
2014/03/05 职场文书
5.12护士节演讲稿
2014/04/30 职场文书
最新离婚协议书范本
2014/08/19 职场文书
党的群众路线教育实践活动整改方案
2014/10/28 职场文书
暑期社会实践新闻稿
2015/07/17 职场文书
SpringBoot连接MySQL获取数据写后端接口的操作方法
2021/11/02 MySQL