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自动化测试之setUp与tearDown实例
Sep 28 Python
Python中字符串的处理技巧分享
Sep 17 Python
使用python实现个性化词云的方法
Jun 16 Python
Python中使用支持向量机SVM实践
Dec 27 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 Python
Python基于sklearn库的分类算法简单应用示例
Jul 09 Python
在Python中使用defaultdict初始化字典以及应用方法
Oct 31 Python
python安装pil库方法及代码
Jun 25 Python
Python中变量的输入输出实例代码详解
Jul 28 Python
使用Windows批处理和WMI设置Python的环境变量方法
Aug 14 Python
Python中对象的比较操作==和is区别详析
Feb 12 Python
利用python实时刷新基金估值(摸鱼小工具)
Sep 15 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实现根据浏览器跳转不同语言页面代码
2013/08/02 PHP
php生成excel文件的简单方法
2014/02/08 PHP
PHP实现支持加盐的图片加密解密
2016/09/09 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
JS动画效果代码3
2008/04/03 Javascript
Web开发者必备的12款超赞jQuery插件
2010/12/03 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
2011/10/17 Javascript
json实现前后台的相互传值详解
2015/01/05 Javascript
jQuery实现高亮显示网页关键词的方法
2015/08/07 Javascript
JavaScript实现输入框(密码框)出现提示语
2016/01/12 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
微信小程序实现左右联动的实战记录
2018/07/05 Javascript
Angular动态绑定样式及改变UI框架样式的方法小结
2018/09/03 Javascript
浅入深出Vue之组件使用
2019/07/11 Javascript
微信小程序全局变量的设置、使用、修改过程解析
2019/09/24 Javascript
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
Python迭代和迭代器详解
2016/11/10 Python
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
python 接口实现 供第三方调用的例子
2019/08/13 Python
使用python计算三角形的斜边例子
2020/04/15 Python
python基于exchange函数发送邮件过程详解
2020/11/06 Python
python录音并调用百度语音识别接口的示例
2020/12/01 Python
html5读取本地文件示例代码
2014/04/22 HTML / CSS
Ralph Lauren拉夫·劳伦美国官网:带有浓郁美国气息的高品味时装品牌
2017/11/01 全球购物
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
计算机应用与科学个人的自我评价
2013/11/15 职场文书
机关党员公开承诺书
2014/08/30 职场文书
大学生第一学年自我鉴定2015
2014/09/28 职场文书
小学秋季运动会报道稿
2014/09/30 职场文书
2014年幼儿园安全工作总结
2014/11/10 职场文书
2015年项目工作总结
2015/04/29 职场文书
2016机关干部作风建设心得体会
2016/01/21 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS