深入探索FastAPI Background Tasks:原理、实践与高级技巧
FastAPI通过Background Tasks提供了一种轻量级异步解决方案,允许开发者在请求响应后继续执行非即时性任务。
一、核心原理1.1 底层机制解析FastAPI的Background Tasks并非基于多线程或多进程,而是利用Python的asyncio事件循环实现异步执行。其核心实现位于starlette.background模块中,具体流程如下:
123456789101112# Starlette源码简析class BackgroundTask: def __init__(self, func: typing.Callable, *args: typing.Any, **kwargs: typing.Any) -> None: self.func = func self.args = args self.kwargs = kwargs async def __call__(self) -> None: if iscoroutinefunction(self.func): ...
使用FastAPI开发高效的Background Tasks
在Web应用开发中,处理耗时任务是一个常见的需求。例如,发送电子邮件、处理大量数据、调用外部API等操作可能会阻塞主线程,导致用户体验下降。FastAPI作为一个高性能的Web框架,提供了强大的Background Tasks功能,允许开发者将这些耗时任务放到后台执行,从而提升应用的响应速度和用户体验。
什么是Background Tasks?Background Tasks是FastAPI提供的一种机制,在请求处理完成后,继续执行一些耗时操作。这些操作不会阻塞主线程,因此可以显著提高应用的响应速度。
原理FastAPI的Background Tasks机制基于Python的asyncio库。当在路由处理函数中定义一个Background Task时,FastAPI会将该任务放入一个任务队列中,并在请求处理完成后异步执行这些任务。由于这些任务是在后台执行的,因此不会影响主线程的响应速度。
如何使用Background Tasks?在FastAPI中使用Background Tasks只需要在路由处理函数中定义一个BackgroundTasks参数,并将需要执行的任务添加到该参数中即可。 ...
文档项目管理工具MkDocs
良好的文档是项目成功的关键。它不仅帮助开发者理解项目结构和代码逻辑,还是新团队成员快速上手的桥梁。MkDocs可以帮助我们构建出既美观又功能丰富的技术文档。
1、mkdocs简介MkDocs 是一个快速、简单且功能丰富的静态站点生成器,专为项目文档设计。它允许你用 Markdown 编写文档,然后通过一个简洁的命令生成一个静态网站。MkDocs 的核心优势在于它的简洁性、速度和易于使用。
主要特点:
纯 Python 编写:不需要复杂的依赖关系。
Markdown 支持:使用 Markdown 编写文档,易于阅读和编写。
静态站点生成:生成静态 HTML 页面,可以轻松部署到任何静态文件服务器或 CDN 上。
实时预览:开发时提供实时预览功能,所见即所得。
自定义主题:支持自定义主题,可以轻松定制文档的外观。
2、MkDocs-MaterialMkDocs-Material 是 MkDocs 的一个非常受欢迎的主题,它基于 Google 的 Material Design。它不仅提供了一个现代、响应式的设计,还包含了许多增强功能,如搜索、版本切换和脚注等。
特点:
响应式设计:适配 ...
SQLModel 关联查询
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697from sqlmodel import Field, Session, SQLModel, create_engine, select, unionclass Team(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(index=True) headquarters: strclass Hero(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) ...
SQLModel 自引用数据模型(多对多)
上文讲了自引用数据模型的一对多场景,主要用于构建树形数据结构。自引用数据模型还有多对多的场景,比如文章引用,参考等等,这个时候需要引入一张中间表来完成。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465from typing import List, Optionalfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engine, selectclass PaperSimilarLink(SQLModel, table=True): paper_id: Optional[int] = Field( default=None, foreign_key="paper.id", primary_key=True ) similar_id: Optional[int] ...
SQLModel 自引用数据模型
自引用表在数据库中是一种比较常见的数据结构,那么在SQLModel中怎么建立一个自引用的数据模型来对应这种数据表呢?主要原理还是参考一对多表结构的数据模型创建方式,在单一模型中建立一对多关系链。
注意:这里需要使用SQLAlchemy中的 remote_site 参数,参见 Relationships API
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061from typing import Optionalfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engineclass Node(SQLModel, table=True): __tablename__ = "node" # 表名 id: Optional[int] = Field(default=None, primary_key ...
SQLModel 关联关系(关联加载方式)
4. lazy加载方式参数lazy是SQLAlchemy的一个参数,定义了多表关联的数据加载方式,关联关系的加载分为三类;延迟加载、急切加载和不加载。
延迟加载是指从查询返回对象,并不加载相关对象。而当第一次在特定对象上访问给定的集合或引用时,会发出附加的 SELECT 语句,以便加载所请求的集合。
预加载是指从查询返回对象,并且相关集合或标量引用已经预先加载。 在这种场景,ORM 可以通过JOIN 来同时加载相关行,或者通过在主语句之后发出附加 SELECT 语句来立即加载集合或标量引用来实现此目的。
不加载是指禁用给定关系的加载,要么该属性为空并且从未加载,要么在访问该属性时引发错误,以防止不需要的延迟加载。
lazy参数在SQLModel中的使用案例如下:
12345678910111213141516171819class User(SQLModel, table=True): user_id: Optional[int] = Field(default=None, primary_key=True) username: str role_id: Opti ...
SQLModel 关联关系(一对一关系)
3. 一对一关系1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071from typing import Optionalfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engineclass Card(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) card_id: str = Field(index=True) card_user: str tel: str detail: Optional["CardDetail"] = Relationship( back_populates="card", ...
SQLModel 关联关系(多对多关系)
2. 多对多关系1234567891011121314151617181920class HeroTeamLink(SQLModel, table=True): team_id: int | None = Field(default=None, foreign_key="team.id", primary_key=True) hero_id: int | None = Field(default=None, foreign_key="hero.id", primary_key=True)class Team(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(index=True) headquarters: str heroes: list["Hero"] = Relationship(back_populates="teams", ...
SQLModel 关联关系(一对多关系)
1. 一对多关系12345678910111213141516class Team(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(index=True) headquarters: str heroes: list["Hero"] = Relationship(back_populates="team")class Hero(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(index=True) secret_name: str age: int | None = Field(default=None, index=True) team_id: int | None = Field(default=None, ...