title: FastAPI与Tortoise-ORM实现关系型数据库关联

date: 2025/04/21 10:51:41

updated: 2025/04/21 10:51:41

author: cmdragon

excerpt:

FastAPI与Tortoise-ORM结合实现关系型数据库关联,支持1:1、1:N和M:N关系。1:N关系通过ForeignKeyField定义,M:N关系使用ManyToManyField处理。Pydantic模型用于数据验证和序列化,路由实现中通过prefetch_related优化查询性能。M:N关系通过中间表操作,支持复杂查询。常见报错包括422验证错误和外键约束失败,可通过事务和类型检查解决。安装依赖后,使用uvicorn启动服务进行测试。

categories:

  • 后端开发
  • FastAPI

tags:

  • FastAPI
  • Tortoise-ORM
  • 关系型数据库
  • 1:N关系
  • M:N关系
  • 异步数据库操作
  • 数据库关联实现


扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

探索数千个预构建的 AI 应用,开启你的下一个伟大创意

一、FastAPI与Tortoise-ORM关系型数据库关联实现

1. 关系型数据库关联基础

在关系型数据库中,表与表之间的关联主要分为三种类型:

  • 1:1关系(如用户与身份证)
  • 1:N关系(如作者与书籍)
  • M:N关系(如学生与课程)

FastAPI通过Tortoise-ORM实现异步数据库操作时,使用ForeignKeyFieldManyToManyField

字段类型处理关联关系。相比同步ORM,异步实现需要特别注意await的使用和查询优化。

2. 1:N关系实现(作者与书籍案例)

2.1 模型定义

# models.py
from tortoise.models import Model
from tortoise import fields class Author(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
# 反向关系查询字段
books = fields.ReverseRelation["Book"] class Book(Model):
id = fields.IntField(pk=True)
title = fields.CharField(max_length=255)
author = fields.ForeignKeyField(
"models.Author",
related_name="books",
on_delete=fields.CASCADE
)

2.2 Pydantic模型

# schemas.py
from pydantic import BaseModel class AuthorCreate(BaseModel):
name: str class BookCreate(BaseModel):
title: str
author_id: int class AuthorOut(BaseModel):
id: int
name: str
books: list[dict] = [] class Config:
orm_mode = True

2.3 路由实现

# main.py
from fastapi import FastAPI, HTTPException
from models import Author, Book
from schemas import AuthorCreate, BookCreate, AuthorOut app = FastAPI() @app.post("/authors/", response_model=AuthorOut)
async def create_author(author: AuthorCreate):
db_author = await Author.create(**author.dict())
return await AuthorOut.from_tortoise_orm(db_author) @app.get("/authors/{author_id}", response_model=AuthorOut)
async def get_author(author_id: int):
author = await Author.get(id=author_id).prefetch_related("books")
if not author:
raise HTTPException(status_code=404, detail="Author not found")
return await AuthorOut.from_tortoise_orm(author)

3. M:N关系实现(学生与课程案例)

3.1 模型定义

# models.py
class Student(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
courses = fields.ManyToManyField(
"models.Course",
related_name="students",
through="student_course"
) class Course(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)

3.2 中间表操作

# 添加选课关系
student = await Student.get(id=1)
course = await Course.get(id=2)
await student.courses.add(course) # 查询学生选课
student_with_courses = await Student.get(id=1).prefetch_related("courses")

3.3 复杂查询示例

# 查询选修数学课的学生
math_students = await Student.filter(
courses__name="Math"
).prefetch_related("courses")

4. 课后Quiz

Q1:当建立1:N关系时,为什么要使用prefetch_related()方法?

A. 提高查询性能

B. 避免循环引用

C. 处理分页请求

D. 验证数据格式

正确答案:A

解析:prefetch_related()用于预加载关联数据,通过单次数据库查询获取所有相关记录,避免N+1查询问题,显著提升查询效率。

Q2:M:N关系中,through参数的作用是什么?

A. 定义中间表名称

B. 指定关联字段类型

C. 设置级联删除规则

D. 声明索引字段

正确答案:A

解析:through参数用于自定义中间表名称,当需要向中间表添加额外字段时,可以显式创建中间模型。

5. 常见报错解决方案

报错1:422 Validation Error

{
"detail": [
{
"loc": [
"body",
"author_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}

解决方法:

  1. 检查请求体数据格式是否符合JSON规范
  2. 确认字段类型与Pydantic模型定义一致
  3. 使用try/except捕获类型转换异常

报错2:IntegrityError外键约束失败

sqlite3.IntegrityError: FOREIGN KEY constraint failed

解决方法:

  1. 检查关联ID是否存在
  2. 确认数据库事务完整性
  3. 使用atomic()包裹关联操作:
async with in_transaction():
author = await Author.create(name="J.K. Rowling")
await Book.create(title="Harry Potter", author=author)

预防建议:

  1. 始终在数据库操作中使用事务
  2. 为关联字段添加索引
  3. 使用select_related和prefetch_related优化查询

运行准备

安装依赖:

pip install fastapi uvicorn tortoise-orm pydantic

启动服务:

uvicorn main:app --reload

通过以上实现,开发者可以完整掌握FastAPI中异步数据库关联操作的核心要点。建议在Postman中测试接口时,重点关注关联数据的完整性和查询效率表现。

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:FastAPI与Tortoise-ORM实现关系型数据库关联 | cmdragon's Blog

往期文章归档:

FastAPI与Tortoise-ORM实现关系型数据库关联的更多相关文章

  1. FastAPI(44)- 操作关系型数据库

    ORM FastAPI 可与任何数据库和任何样式的库配合使用并和数据库通信 object-relational mapping 对象关系映射 ORM 具有在代码和数据库表(关系)中的对象之间进行转换( ...

  2. Teradata 认证系列 - 3. 关系型数据库的概念

    本课的学习目标 定义关系型数据库关联的术语 讨论主键的功能 讨论外键的功能 列出关系型数据库的优势 描述星型架构和第三范式数据模型的区别 什么是数据库?数据库是一个应用永久保存数据的集合表现在: 逻辑 ...

  3. Node的关系型数据库ORM库:bookshelf

    NodeJs 关系数据库ORM库:Bookshelf.js bookshelf.js是基于knex的一个关系型数据库的ORM库.简单易用,内置了Promise的支持.这里主要罗列一些使用的例子,例子就 ...

  4. [Oracle] 关系型数据库排序算法和数据结构以及关联查询

    关系型数据库排序算法和数据结构以及关联查询 1. Merge sort 理解merge sort算法将有助于更好地理解数据库join操作 - merge join 算法逻辑 将2个有序的大小为N/2的 ...

  5. Daject初探 - 一个开源关系型数据库对象关系映射(ORM)模型

    Daject简介 Daject是用php写的一个关系型数据库抽象模型,通过该模型,可以在不写任何SQL或写很少的SQL就能执行大多数数据库查询操作.Daject具有面向对象,跨数据库的优点,通过数据库 ...

  6. ORM初识和数据库操作

    ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据库之 ...

  7. ORM对象关系型映射的用法

    ORM对象关系型映射的用法 -- Django模型 1.什么是ORM关系型映射 ORM 全拼Object-Relation Mapping. 中文意为 对象-关系映射. 主要实现模型对象到关系数据库数 ...

  8. 非关系型数据库(NoSql)

    最近了解了一点非关系型数据库,刚刚接触,觉得这是一个很好的方向,对于大数据 方面的处理,非关系型数据库能起到至关重要的地位.这里我主要是整理了一些前辈的经验,仅供参考. 关系型数据库的特点 1.关系型 ...

  9. 非关系型数据库来了,CRL快速开发框架升级到版本4

    轮子?,我很任性,我要造不一样的轮子,同时支持关系型和非关系型的框架有没有 新版数据查询作了些调整,抽象了LabmdaQueryy和DBExtend,升级到版本4,非关系数据库MongoDB被支持了! ...

  10. 关系型数据库与NOSQL

    本文转载自: http://www.cnblogs.com/chay1227/archive/2013/03/17/2964020.html(只作转载, 不代表本站和博主同意文中观点或证实文中信息) ...

随机推荐

  1. 00.嵌入式笔记——初识make工具和Makefile文件

    1. make工具和Makefile文件 make是解决大工程编译的工具,描述哪些文件需要编译.哪些需要重新编译的文件就叫做 Makefile,Makefile 就跟脚本文件一样,Makefile 里 ...

  2. delphi DateUtils强大的时间功能集成

    初步说明: CompareDate 比较两个日期时间值日期部分的大小CompareDateTime 比较两个日期时间值的大小CompareTime 比较两个日期时间值时间部分的大小DateOf 去除日 ...

  3. 春节福利来啦!Mac用户快来抽大奖

    亲爱的Mac俱乐部(MaClub)用户及所有果粉朋友们: 值此新春佳节之际,Mac俱乐部特别推出春节抽奖活动,以回馈广大用户长期以来的支持与厚爱.我们精心准备了丰富的奖品,希望能为您的新年增添一份惊喜 ...

  4. Q:oracle通过正则表达式替换对应值

    示例 把http://192.168.1.1:8888/a.html中的192.168.1.1:8888/替换成172.32.32.1:9999/ SELECT replace('http://192 ...

  5. Q:oracle备份表语句

    oracle备份还原表语句 方法1.sql语句(同一数据库服务器) 备份 create table xxx_temp as select * from xxx; 还原 truncate table x ...

  6. MySQL主从复制-原理实战

    一.原理 主从复制架构图:主从复制原理: Mysql 中有一种日志叫做 bin 日志(二进制日志).这个日志会记录下所有修改了数据库的SQL 语句(insert,update,delete,creat ...

  7. 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!

    前言 腾讯元宝AI产品于2025年2月13日在应用商店发布更新,正式接入了DeepSeek R1模型,并宣布该模型已联网.满血上线,DeepSeek+腾讯混元,好用不卡机. 腾讯元宝介绍 腾讯元宝是依 ...

  8. 川崎机器人维修kasawaki维护注意事项

    为确保川崎机械臂的正确安全操作.防止人员伤害和财产损失,请遵守下述方框符号表达的安全信息. --注意事项 在进行Kasawaki川崎机器人维修操作前,请注意如下事项以确保安全. 1. 在开始检查之前, ...

  9. Datagrip 破解

    题记部分 方法一 [参考链接]:DataGrip 2023.2最新安装使用教程(附激活码,亲测好用)_糖果果爱分享的技术博客_51CTO博客 [软件版本]:datagrip-2023.3.4.win ...

  10. 初探PApplet窗口打开方式(Processing程序)

    使用Processing快6年了,是时候回过头来看看它的"main"方法了,也就是它从哪出生的?~~~ 源码学习 ///////////////////////////////// ...