FastApi学习第三天:两表联查

news2024/11/25 2:54:52

两表联查

在这里插入图片描述

在 FastAPI 中,使用 Tortoise ORM 查询两表联查(通常是通过外键关系进行联接)是非常简单的。可以使用 select_relatedprefetch_related 来执行联表查询,它们类似于 Django ORM 的 select_relatedprefetch_related,用于优化查询的效率。

1. select_related vs prefetch_related

在这里插入图片描述

  • select_related:用于执行 SQL JOIN 查询。适用于一对一或外键关系。会一次性加载相关的表,减少数据库查询次数。
  • prefetch_related:用于执行多次查询,但在应用程序中将多个查询合并。适用于多对多关系或者反向外键关系。

示例:使用 select_relatedprefetch_related 进行联查

假设我们有以下两个模型:AuthorBookBook 通过外键引用 Author
在这里插入图片描述

1. 定义模型
from tortoise import fields
from tortoise.models import Model

class Author(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100)

    def __str__(self):
        return self.name

class Book(Model):
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=100)
    author = fields.ForeignKeyField('models.Author', related_name='books')

    def __str__(self):
        return self.title

在这个例子中,Book 模型通过 ForeignKeyFieldAuthor 模型建立了外键关系。

2. 使用 select_related 进行联查

select_related 会对外键关系进行优化,执行 JOIN 操作,在同一个查询中一次性获取 AuthorBook 数据。它适用于一对一关系和外键关系。
在这里插入图片描述

查询某本书及其作者
@app.get("/books/{book_id}")
async def get_book(book_id: int):
    book = await Book.filter(id=book_id).select_related('author').first()
    if not book:
        raise HTTPException(status_code=404, detail="Book not found")
    return {"book_title": book.title, "author_name": book.author.name}
  • select_related('author'):这将通过 SQL JOIN 操作将 BookAuthor 的数据一次性加载。
  • .first():如果查询没有找到数据,则返回 None

SQL 查询的效果

SELECT "book"."id", "book"."title", "author"."id", "author"."name"
FROM "book"
JOIN "author" ON "book"."author_id" = "author"."id"
WHERE "book"."id" = ?

3. 使用 prefetch_related 进行联查

prefetch_related 适用于多对多关系或反向外键关系,它会执行额外的查询并在应用程序中合并它们。适用于需要加载多个相关对象的场景。

查询所有作者及其所有书籍
@app.get("/authors/")
async def get_authors():
    authors = await Author.all().prefetch_related('books')
    result = []
    for author in authors:
        result.append({
            "author_name": author.name,
            "books": [book.title for book in author.books]
        })
    return result
  • prefetch_related('books'):这将执行两次查询,一个查询所有 Author 数据,另一个查询所有与 Author 相关的 Book 数据,并在应用程序中将它们合并。

SQL 查询的效果

SELECT "author"."id", "author"."name" FROM "author";

SELECT "book"."id", "book"."title", "book"."author_id"
FROM "book"
WHERE "book"."author_id" IN (?, ?, ?)

4. 复杂查询:联查和过滤

在这里插入图片描述

可以将 select_relatedprefetch_related 与其他查询操作(如 filterorder_by)结合使用,进行更复杂的查询。

查询某位作者的所有书籍,并按书名排序
@app.get("/authors/{author_id}/books")
async def get_author_books(author_id: int):
    author = await Author.get(id=author_id)
    books = await author.books.all().order_by('title')
    return [{"title": book.title} for book in books]
  • author.books.all() 查询该作者所有的书籍,并按书名升序排序。

5. 联查性能优化

  • 使用 select_related 时,可以减少数据库查询次数,因为它会合并查询成一个 JOIN 查询。
  • prefetch_related 在数据量较大的情况下可能更有效,因为它可以分开多个查询并在应用层合并它们,从而避免了一次性加载大量数据导致的性能问题。

6. 示例:获取所有书籍及其作者信息

查询所有书籍,并获取每本书的作者信息,使用 select_related 来优化查询。

@app.get("/books/")
async def get_books():
    books = await Book.all().select_related('author')
    return [
        {"book_title": book.title, "author_name": book.author.name}
        for book in books
    ]

这个查询将会加载所有书籍及其对应的作者,select_related('author') 会通过 JOIN 查询把 BookAuthor 的数据合并在一个查询中,减少数据库查询次数。

总结

  • select_related 适用于外键关系或一对一关系,使用 SQL JOIN 优化查询。
  • prefetch_related 适用于多对多关系或反向外键关系,执行多次查询并在应用程序中合并它们。
  • 通过使用 select_relatedprefetch_related,你可以有效地优化数据库查询,减少数据库请求次数和加载的时间。

这些工具使得在 FastAPI 和 Tortoise ORM 中进行联表查询变得非常高效和灵活。

查询同时满足不同表的属性过滤

在 Tortoise ORM 中,进行多条件查询时,可以通过 filter 方法同时指定多个条件。你可以在 filter 中传递多个参数,以实现书名和作者同时符合条件的查询。

假设你想查询符合以下条件的书籍:

  • 书名包含某个关键词。
  • 作者的名字也包含某个关键词。

下面是如何使用 filter 方法实现这两个条件的查询。

示例:查询书名和作者符合条件的书籍

假设我们有 BookAuthor 模型,并且希望根据书名和作者名同时过滤书籍。

1. 定义模型

在这里插入图片描述

from tortoise import fields
from tortoise.models import Model

class Author(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100)

    def __str__(self):
        return self.name

class Book(Model):
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=100)
    author = fields.ForeignKeyField('models.Author', related_name='books')

    def __str__(self):
        return self.title
2. 多条件查询:书名和作者名

在这里插入图片描述

假设你想查询所有书名包含 “Python” 且作者名包含 “John” 的书籍。你可以使用 filter 来组合这两个条件。

from fastapi import FastAPI, HTTPException
from tortoise.exceptions import DoesNotExist

@app.get("/books/")
async def get_books_by_conditions(title_contains: str, author_contains: str):
    books = await Book.filter(
        title__icontains=title_contains,  # 书名包含指定关键词
        author__name__icontains=author_contains  # 作者名包含指定关键词
    ).select_related('author')  # 联接查询,获取作者信息

    if not books:
        raise HTTPException(status_code=404, detail="No books found matching the criteria")

    return [
        {"book_title": book.title, "author_name": book.author.name}
        for book in books
    ]
3. 解释
  • title__icontains=title_contains__icontains 是 Tortoise ORM 提供的查询方式,表示不区分大小写地查询包含某个子串的值。title_contains 是你传递的参数,表示书名应包含的关键词。
  • author__name__icontains=author_containsauthor__name__icontains 是通过外键 author 查询 Author 模型中的 name 字段,同样表示不区分大小写地查询包含作者名字的子串。
4. 查询请求示例

当你调用 GET /books/ 接口时,可以传递书名和作者名的查询参数,例如:

GET /books/?title_contains=python&author_contains=john

这将返回所有书名包含 “python” 且作者名包含 “john” 的书籍。

5. 更多的查询条件

你可以通过组合不同的条件来实现更复杂的查询。例如:

  • 精确匹配:title__exact='Python 101'
  • 以某个值开始:title__startswith='Python'
  • 以某个值结束:title__endswith='Guide'
  • 进行日期范围查询等。
示例:查询书名包含 “Python” 且创建日期在某个范围内的书籍
from datetime import datetime

@app.get("/books/date-range")
async def get_books_by_date_range(start_date: datetime, end_date: datetime):
    books = await Book.filter(
        title__icontains="Python",
        created_at__gte=start_date,
        created_at__lte=end_date
    ).select_related('author')

    return [{"book_title": book.title, "author_name": book.author.name} for book in books]

总结

  • 使用 filter 方法可以实现多条件查询。
  • 可以通过字段查询条件(如 icontainsexactstartswith 等)来筛选数据。
  • 通过使用外键字段(例如 author__name)进行联查,能够同时查询两表相关联的数据。

这样就可以灵活地根据书名和作者的多个条件查询数据,并通过 FastAPI 提供给客户端使用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis原理及应用

Redis简介 Redis是开源的(BSD许可),数据结构存储于内存中,被用来作为数据库,缓存和消息代理。它支持多种数据结构,例如:字符串(string),哈希(hash…

Unity类银河战士恶魔城学习总结(P141 Finalising ToolTip优化UI显示)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ UI部分暂时完结!!! 本章节优化了UI中物品描述的显示效果,技能描述的显示效果 并且可以批…

oracle的静态注册和动态注册

oracle的静态注册和动态注册 静态注册: 静态注册 : 指将实例的相关信息手动告知 listener 侦 听 器 , 可以使用netmgr,netca,oem 以及直接 vi listener.ora 文件来实现静态注册,在动态注册不稳定时使用,特点是:稳定&…

社交电商专业赋能高校教育与产业协同发展:定制开发AI智能名片及2+1链动商城小程序的创新驱动

摘要:本文围绕社交电商有望成为高校常态专业这一趋势展开深入探讨,剖析国家政策认可下其学科发展前景,着重阐述在专业建设进程中面临的师资短缺及实践教学难题。通过引入定制开发AI智能名片与21链动商城小程序,探究如何借助这些新…

数据指标与标签在数据分析中的关系与应用

导读:分享数据指标体系的文章很多,但讲数据标签的文章很少。实际上,标签和指标一样,是数据分析的左膀右臂,两者同样重要。实际上,很多人分析不深入,就是因为缺少对标签的应用。今天系统的讲解下…

使用Electron将vue2项目打包为桌面exe安装包

目录 一、下载electron模板项目 【electron-quick-start】​ 二、打开项目,安装所有依赖 三、在打exe包的时候报错是因为没有,需要检查并安装之后重新打包; 四、经过这么疯狂的一波操作之后,就可以打包出你想要的exe安装包&am…

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

Linux之NFS共享文件操作

一、注意点 以下操作使用root用户 代理端需要访问服务端的2049、111端口二、nfs下载 # 服务端和代理端都要安装 yum –y install rpcbind yum –y install nfs-utils三、配置共享目录-【服务端】 *修改/etc/exports文件,追加以下内容 /home/app_adm/test ip1(in…

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云 C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用 发布于 2021-06-10 00:10:59 7.1K0 举报 文章被收录于专栏:c#学习笔记 一、介绍 DockPanelSuite是托管在…

杰发科技AC7840——EEP中RAM的配置

sample和手册中示例代码的sram区地址定义不一样 这个在RAM中使用没有限制,根据这个表格留下足够空间即可 比如需要4096字节的eep空间,可以把RAM的地址改成E000,即E000-EFFF,共4096bytes即可。

web-03

CSS回顾 选择器 标签选择器 标签{}ID选择器 标签中定义ID属性。 #ID值{}类选择器 标签中使用class属性 .类名{}关于DIV/span div任意的大小的长方形,大小css: width, height控制。—换行 span-- 一行内 CSS常用属性 width/height 宽度/高度 定义&…

CI配置项,IT服务的关键要素

随着现今数字经济的不断发展,逐渐成熟的IT 基础设施已不再是简单的竞争优势,而已成为企业生存和发展的基石。然而,仅仅拥有强大的基础设施是不够的。为了保障 IT 服务的平稳运行和持续交付,企业还需要重点关注 IT 服务的核心构建模…

ApiChain-编写迭代单测用例

项目地址:ApiChain 项目主页 写单测用例,就像画一幅有向不循环的图,图中的每个节点是这个单测用例的每一个步骤,连线代表着数据的流向,这幅图通常有一个或者多个起点,但通常只有一个终点。起点的数据来源于…

九、FOC原理详解

1、FOC简介 FOC(field-oriented control)为磁场定向控制,又称为矢量控制(vectorcontrol),是目前无刷直流电机(BLDC)和永磁同步电机(PMSM)高效控制的最佳选择…

企业OA管理系统:Spring Boot技术实现与案例研究

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足,创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管理系统的系统分析部…

【tensorflow的安装步骤】

创建一个虚拟环境 conda create -n tensorflow python3.6激活虚拟环境 conda activate tensorflow使用镜像源下载 pip install tensorflow1.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/特别特别重要的点!!! 别用WiFi或者校园网下…

网络安全-web架构-nginx配置

1. nginx访问: 访问的是index.html, 访问ip访问的资源就是在/usr/share/nginx/html中; 当nginx不认识,浏览器认识的话,浏览器会自动渲染。 当nginx认识,浏览器不认识的话,浏览器会把它加载成…

ES6 模块化语法

目录 ES6 模块化语法 分别暴露 统一暴露 ​编辑 默认暴露 ES6 模块化引入方式 ES6 模块化语法 模块功能主要由两个命令构成:export 和 import。 ⚫ export 命令用于规定模块的对外接口(哪些数据需要暴露,就在数据前面加上关键字即可…

基于Java Springboot高校洗浴管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

stm32如何接收舵机的控制信号(而不是控制舵机)

看到很多如何stm32用pwm信号控制舵机的文章,老生常谈了 我来写一个stm32接收pwm信号的例子 ,这个pwm信号是用来控制舵机的 背景: 我需要接收航模接收机的,用来控制舵机的pwm信号, 得到这个信号后,做其他事情. 初版代码 pwm.h#ifndef _pwm_H #define _pwm_H#include "s…