异步编程与Tortoise-ORM框架

打印 上一主题 下一主题

主题 1972|帖子 1972|积分 5916

title: 异步编程与Tortoise-ORM框架
date: 2025/04/19 00:13:05
updated: 2025/04/19 00:13:05
author: cmdragon
excerpt:
异步编程通过async/await语法实现协程,单线程可处理惩罚多个并发请求,适合IO麋集型场景。Tortoise-ORM专为异步设计,支持完整ORM功能和多种数据库,与Pydantic深度集成。整合FastAPI时,通过register_tortoise初始化ORM,利用in_transaction管理事件,确保操作原子性。常见问题包括未利用await返回协程对象和事件循环关闭错误,需通过正确的事件循环启动和事件管明白决。
categories:

  • 后端开发
  • FastAPI
tags:

  • 异步编程
  • Tortoise-ORM
  • FastAPI
  • 协程机制
  • 数据库事件
  • Pydantic集成
  • 异步IO
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
探索数千个预构建的 AI 应用,开启你的下一个伟大创意
第一章:异步编程底子与Tortoise-ORM框架定位

1.1 异步IO原理与协程机制

当你在快餐店列队时,同步IO就像站在队列中干等取餐,而异步IO则是先下单后去玩手机,听到叫号再取餐。现代Web应用需要同时服务成千上万个这样的"
顾客",这正是异步编程的价值所在。
Python通过async/await语法实现协程:
  1. async def fetch_data():
  2.     # 模拟IO操作
  3.     await asyncio.sleep(1)
  4.     return {"data": "result"}
  5. # 事件循环驱动执行
  6. async def main():
  7.     task1 = fetch_data()
  8.     task2 = fetch_data()
  9.     await asyncio.gather(task1, task2)  # 并发执行
  10. asyncio.run(main())
复制代码
关键点解析:

  • async def 声明异步函数(协程)
  • await 将控制权交还事件循环
  • 单个线程可处理惩罚多个并发请求
与传统同步模型对比:
指标同步模式异步模式线程利用1请求1线程单线程处理惩罚多请求IO等待处理惩罚阻塞非阻塞适合场景CPU麋集型IO麋集型1.2 Tortoise-ORM的异步设计哲学

传统ORM(如Django ORM)在异步环境中会形成性能瓶颈。Tortoise-ORM专为异步而生,其架构设计出现以下特点:
  1. from tortoise.models import Model
  2. from tortoise import fields
  3. class User(Model):
  4.     id = fields.IntField(pk=True)
  5.     name = fields.CharField(max_length=50)
  6.     created_at = fields.DatetimeField(auto_now_add=True)
  7.     class Meta:
  8.         table = "auth_user"
复制代码
框架核心上风:

  • 完整的ORM功能支持(关系、事件、聚合)
  • 原生异步查询接口设计
  • 支持PostgreSQL/MySQL/SQLite
  • 与Pydantic深度集成
1.3 整合FastAPI的完整示例

创建具备完整功能的API端点:
  1. from fastapi import FastAPI, Depends
  2. from tortoise.contrib.fastapi import register_tortoise
  3. from pydantic import BaseModel
  4. app = FastAPI()
  5. # 请求体模型
  6. class UserCreate(BaseModel):
  7.     name: str
  8. # 响应模型
  9. class UserOut(UserCreate):
  10.     id: int
  11.     created_at: datetime
  12. # 数据库配置
  13. DB_CONFIG = {
  14.     "connections": {"default": "sqlite://db.sqlite3"},
  15.     "apps": {
  16.         "models": {
  17.             "models": ["__main__"],  # 自动发现当前模块的模型
  18.             "default_connection": "default",
  19.         }
  20.     },
  21. }
  22. # 注册Tortoise-ORM
  23. register_tortoise(
  24.     app,
  25.     config=DB_CONFIG,
  26.     generate_schemas=True,  # 自动建表
  27.     add_exception_handlers=True,
  28. )
  29. # 依赖注入数据库连接
  30. async def get_db():
  31.     async with in_transaction() as conn:
  32.         yield conn
  33. @app.post("/users", response_model=UserOut)
  34. async def create_user(user: UserCreate, conn=Depends(get_db)):
  35.     """
  36.     创建用户并返回完整数据
  37.     使用事务保证原子性操作
  38.     """
  39.     db_user = await User.create(**user.dict(), using_db=conn)
  40.     return UserOut.from_orm(db_user)
复制代码
代码要点解析:

  • register_tortoise 实现ORM初始化
  • in_transaction 管理事件作用域
  • using_db 参数确保利用同一连接
  • from_orm 自动转换模型为Pydantic对象
课后Quiz

Q1:当数据库查询未利用await时会导致什么现象?
A. 立即返回查询结果
B. 抛出RuntimeWarning
C. 返回coroutine对象
D. 步伐崩溃
正确答案:C
解析:异步函数必须利用await实行,否则将返回未被实行的协程对象,这是常见的初学者错误。
Q2:怎样确保多个更新操作在同一个事件中?
A. 利用@transaction装饰器
B. 手动begin/commit
C. 通过in_transaction上下文管理器
D. 所有操作自动在事件中
正确答案:C
解析:async with in_transaction() as conn会创建事件作用域,所有在该上下文中的操作利用同一个连接。
常见报错办理方案

问题1:422 Unprocessable Entity
  1. {
  2.   "detail": [
  3.     {
  4.       "loc": [
  5.         "body",
  6.         "name"
  7.       ],
  8.       "msg": "field required",
  9.       "type": "value_error.missing"
  10.     }
  11.   ]
  12. }
复制代码
缘故原由分析:

  • 请求体缺少name字段
  • 字段范例不匹配(如数字传字符串)
  • Pydantic模型校验失败
办理方案:

  • 检查请求体是否符合API文档
  • 利用Swagger UI进行测试
  • 查看模型字段定义是否包含required=True
问题2:RuntimeError: Event loop is closed
产生场景:
  1. # 错误写法
  2. async def get_data():
  3.     await User.all()
  4. # 同步上下文中直接调用
  5. get_data()  
复制代码
正确处理惩罚:
  1. async def main():
  2.     await get_data()
  3. if __name__ == "__main__":
  4.     import asyncio
  5.     asyncio.run(main())
复制代码
预防建议:

  • 始终通过事件循环启动异步步伐
  • 在FastAPI路由中自动管理事件循环
  • 避免在同步代码中直接调用协程
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:异步编程与Tortoise-ORM框架 | cmdragon's Blog
往期文章归档:

<ul>FastAPI数据库集成与事件管理 | cmdragon's Blog
FastAPI与SQLAlchemy数据库集成 | cmdragon's Blog
FastAPI与SQLAlchemy数据库集成与CRUD操作 | cmdragon's Blog
FastAPI与SQLAlchemy同步数据库集成 | cmdragon's Blog
SQLAlchemy 核心概念与同步引擎配置详解 | cmdragon's Blog
FastAPI依赖注入性能优化策略 | cmdragon's Blog
FastAPI安全认证中的依赖组合 | cmdragon's Blog
FastAPI依赖注入系统及调试本领 | cmdragon's Blog
FastAPI依赖覆盖与测试环境模拟 | cmdragon's Blog
FastAPI中的依赖注入与数据库事件管理 | cmdragon's Blog
FastAPI依赖注入实践:工厂模式与实例复用的优化策略 | cmdragon's Blog
FastAPI依赖注入:链式调用与多级参数通报 | cmdragon's Blog
FastAPI依赖注入:从底子概念到应用 | cmdragon's Blog
FastAPI中实现动态条件必填字段的实践 | cmdragon's Blog
FastAPI中Pydantic异步分布式唯一性校验 | cmdragon's Blog
掌握FastAPI与Pydantic的跨字段验证本领 | cmdragon's Blog
FastAPI中的Pydantic暗码验证机制与实现 | cmdragon's Blog
深入掌握FastAPI与OpenAPI规范的高级适配本领 | cmdragon's Blog
Pydantic字段元数据指南:从底子到企业级文档增强 | cmdragon's Blog
Pydantic Schema天生指南:自定义JSON Schema | cmdragon's Blog
Pydantic递归模型深度校验36计:从无限嵌套到亿级数据的优化法则 | cmdragon's Blog
Pydantic异步校验器深:构建高并发验证系统 | cmdragon's Blog
Pydantic根校验器:构建跨字段验证系统 | cmdragon's Blog
Pydantic配置继续抽象基类模式 | cmdragon's Blog
Pydantic多态模型:用辨别器构建范例安全的API接口 | cmdragon's Blog
FastAPI性能优化指南:参数解析与惰性加载 | cmdragon's Blog
FastAPI依赖注入:参数共享与逻辑复用 | cmdragon's Blog
FastAPI安全防护指南:构建坚不可摧的参数处理惩罚体系 | cmdragon's Blog
FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 | cmdragon's Blog
FastAPI 核心机制:分页参数的实现与最佳实践 | cmdragon's Blog
<a href="https://blog.cmdragon.cn/posts/615a966b68d9/" target="_blank" rel="noopener nofollow">FastAPI 错误处理惩罚与自定义错误消息完全指南:构建健壮的 API 应用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表