flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询

 
  • 一对多,多对多是什么?

一对多。例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级。

多对多。例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生。

  • 一对多查询

如果一个项目,有两张表。分别是班级表,学生表。

在设计数据表时,我们给学生表设置一个外键,指向班级表的 id 。

sqlalchemy 模板创建表的代码:

 1 from flask import Flask, render_template, request, flash, redirect
2 from flask_sqlalchemy import SQLAlchemy
3
4 app = Flask(__name__,static_folder="static",template_folder="templates")
5
6 # 设置数据库连接属性
7 app.config['SQLALCHEMY_DATABASE_URI'] = '×××'
8 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
9
10 # 实例化 ORM 操作对象
11 db = SQLAlchemy(app)
12
13 # 班级表
14 class Classes(db.Model):
15 __tablename__ = "classes"
16 id = db.Column(db.Integer,primary_key=True)
17 name = db.Column(db.String(20),nullable=False,unique=True)
18
19 # 学生表
20 class Students(db.Model):
21 __tablename__ = "students"
22 id = db.Column(db.Integer,primary_key=True)
23 name = db.Column(db.String(40),nullable=False)
24 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)

flask 中orm关系映射 sqlalchemy的查询的更多相关文章

  1. elasticsearch中的mapping映射配置与查询典型案例

    elasticsearch中的mapping映射配置与查询典型案例 elasticsearch中的mapping映射配置示例比如要搭建个中文新闻信息的搜索引擎,新闻有"标题".&q ...

  2. Django中的ORM关系映射查询方面

    ORM:Object-Relation Mapping:对象-关系映射 在MVC框架中的Model模块中都包括ORM,对于开发人员主要带来了如下好处: 实现了数据模型与数据库的解耦,通过简单的配置就可 ...

  3. Hibernate 中对象关系映射(ObjectRelationMapping)

    1.什么是对象关系映射? 解析:对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说, ...

  4. Hibernate(三)——框架中的关系映射

    在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...

  5. 【Flask】ORM关系以及一对多

    ### ORM关系以及一对多:mysql级别的外键,还不够ORM,必须拿到一个表的外键,然后通过这个外键再去另外一张表中查找,这样太麻烦了.SQLAlchemy提供了一个`relationship`, ...

  6. 170905-MyBatis中的关系映射

    ===关系映射=== 参考文档复习:1对1,1对多,多对多 1.映射(多)对一.(一)对一的关联关系 1).使用列的别名 ①.若不关联数据表,则可以得到关联对象的id属性 ②.若还希望得到关联对象的其 ...

  7. mybatis中一对一关系映射

    一对一关系中普通的配置方式 一.多表连接查询语句: <select id="selectStudentWithAddress" parameterType="int ...

  8. Hibernate框架(三)框架中的关系映射

    在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...

  9. Mybatis中对象关系映射

    在实际开发中,实体类之间有一对一.一对多.多对多的关系,所以需要正确配置它们对应关系,Mybatis通过配置文件能够从数据库中获取列数据后自动封装成对象. 如:一个订单Orders类对应一个用户Use ...

随机推荐

  1. Linux之备份(tar)/解压与压缩(gzip,bzip2,xz)【待完善】

    [本博文,待完善] 以data原始文件为例,同tar备份,用xz压缩,实现备份->压缩整个过程的正向过程(生成.tar.xz)与其逆过程(先解压,后还原备份文件) 1.备份(tar) tar - ...

  2. 第20月第18天 小码哥swift

    1. 9月12日第一次更新 第二篇玩转[斗鱼直播APP]系列之界面分析 第三篇玩转[斗鱼直播APP]系列之项目部署 第四篇玩转[斗鱼直播APP]系列之获取APP图片资源 第五篇玩转[斗鱼直播APP]系 ...

  3. 前端下载excel打不开求助+解法

    解法: //axios   return request({ url: "/saleUnit/exportSaleUnit", headers: { "biz-sourc ...

  4. python - zipfile模块

    import zipfile # f=zipfile.ZipFile(filename, mode="r", compression=ZIP_STORED, allowZip64= ...

  5. php编程 之 php进阶练习

    1,php的date相关操作: PHP date() 函数可把时间戳格式化为可读性更好的日期和时间. <?php echo date("Y/m/d") . "< ...

  6. 用例该如何书写?完整示例-QQ登录界面

    测试用例(case\测试点):指导软件测试工程师找bug的(思想逻辑的整理) 意义:1:怕忘:2:存档(让新人熟悉:产出):3:回归测试(软件即将上线之前,重新执行测试用例)--确认测试 书写测试用例 ...

  7. python标准库之argparse

    argparse的使用 argparse 是 Python 内置的一个用于命令项选项与参数解析的模块,通过在程序中定义好我们需要的参数,argparse 将会从 sys.argv 中解析出这些参数,并 ...

  8. Tomcat 打开jmx

    jmx 配置后可以通过windows java客户端自带的jconsole.exe配置登陆,直观的查看jvm的情况及系统的各项指标: 一.配置linux下tomcat的jmx 具体配置如下,如果生产环 ...

  9. JavaScript使用方法和技巧大全

        有些时候你精通一门语言,但是会发现你其实整天在和其它语言打交道,也许你以为这些微不足道,不至于影响你的开发进度,但恰恰是这些你不重视的东西会浪费你很多时间,我一直以为我早在几年前就已经精通Ja ...

  10. 题解-UOJ284 快乐游戏鸡

    Problem uoj 题意大意: 一棵树,点权\(w_i\),每次玩家可以在树上行走,一条边需要\(1\)的时间,只能往儿子走.每次游戏需要从\(s\)到\(t\). 玩家有一个总死亡次数,初始为\ ...