# fastapi_tortoise **Repository Path**: duans/fastapi_tortoise ## Basic Information - **Project Name**: fastapi_tortoise - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-24 - **Last Updated**: 2026-03-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # fastapi中集成Tortoise-ORM 在 FastAPI 中使用 **Tortoise-ORM** 是一个非常流行的选择,因为 Tortoise-ORM 是异步的(基于 `asyncio`),与 FastAPI 的非阻塞特性完美契合。 官方推荐使用 **`tortoise-fastapi`** 扩展库来简化集成过程,它提供了初始化和中间件,自动处理数据库连接的开启和关闭。 以下是完整的集成步骤: ## **1. 安装依赖** 你需要安装 `tortoise-orm`、`fastapi` 以及 `tortoise-fastapi`。如果你使用 MySQL 或 PostgreSQL,还需要安装对应的驱动(如 `aiomysql` 或 `asyncpg`)。 ```python # 基础安装 (使用 SQLite 为例) pip install fastapi uvicorn tortoise-orm tortoise-fastapi # 如果使用 MySQL pip install aiomysql # 如果使用 PostgreSQL pip install asyncpg ``` ## **2. 项目结构示例** 假设你的项目结构如下: ``` my_project/ ├── main.py ├── models.py └── routers.py ``` ## **3. 定义模型 (**`models.py`**)** Tortoise-ORM 的模型定义与 Django 非常相似。 ```python # models.py from tortoise import fields, models class User(models.Model): id = fields.IntField(pk=True) username = fields.CharField(max_length=50, unique=True) email = fields.CharField(max_length=100) created_at = fields.DatetimeField(auto_now_add=True) def __str__(self): return self.username # 注意:Tortoise 需要显式注册模型,通常在初始化配置中完成 ``` ## 4. 配置与初始化 (app.py) 这是最关键的一步。我们需要使用 `register_tortoise` 来初始化数据库连接。 ```python # main.py from fastapi import FastAPI from tortoise_fastapi import register_tortoise from models import User # 导入模型以触发注册(或者在配置中指定) from routers import router app = FastAPI() # 注册路由 app.include_router(router) # 配置 Tortoise ORM TORTOISE_ORM = { "connections": { # 这里以 SQLite 为例,生产环境请替换为 MySQL/PostgreSQL "default": "mysql://user:password@host:3306/dbname" # PostgreSQL: "postgres://user:password@host:5432/dbname" # "sqlite3": "sqlite://db.sqlite3" }, "apps": { "models": { "models": ["models"], # 指定模型所在的模块路径 "default_connection": "default", } }, "use_tz": False, "timezone": "UTC" } # 注册 Tortoise 到 FastAPI 应用 # generate_schemas=True 表示自动创建表(开发环境方便,生产环境建议用 migrate) register_tortoise( app, config=TORTOISE_ORM, generate_schemas=True, add_exception_handlers=True, # 自动添加一些数据库异常处理 ``` routers.py ```python from fastapi import APIRouter from models import User from tortoise.exceptions import DoesNotExist # 创建路由实例对象 router = APIRouter() # 注册路径处理函数 @router.get("/users") async def users(): # 查询所有的用户数据 users = await User.all() return {"status": True, "msg": "success", "users": users} @router.get("/users/{user_id}") async def users(user_id: int = None): try: # 查询指定用户数据 user = await User.get(id=user_id) return {"status": True, "msg": "success", "data": user} except DoesNotExist: return {"status": False, "msg": "数据不存在"} from pydantic import BaseModel class UserInModel(BaseModel): username:str email:str # 新增用户数据 @router.post('/users') async def create_user(body:UserInModel): user=await User.create(username=body.username,email=body.email) return {"status":True,"msg":"success","data":user} @router.put('/users/{user_id}') async def update_user(user_id:int,body:UserInModel): try: # 查询指定用户数据 user=await User.get(id=user_id) except DoesNotExist: return {"status":False,"msg":"数据不存在"} # 更新用户数据 user.username=body.username user.email=body.email # 保存更新 await user.save() return {"status":True,"msg":"success","data":user} # 删除用户 @router.delete('/users/{user_id}') async def delete_user(user_id:int): try: # 查询指定用户数据 user=await User.get(id=user_id) except DoesNotExist: return {"status":False,"msg":"数据不存在"} # 删除用户数据 await user.delete() return {"status":True,"msg":"success"} ``` ## **5. 运行与测试** 启动服务器: ```shell uvicorn main:app --reload ``` 访问 `http://127.0.0.1:8000/users` 即可看到数据。首次运行时,`generate_schemas=True` 会自动在数据库中创建 `user` 表。 ## **6. 高级用法:Pydantic 模型集成** 为了获得更好的 API 文档(Swagger UI)和数据验证,通常会将 Tortoise 模型与 Pydantic 模型结合。 **方法 A:手动定义 Pydantic 模型(推荐,控制力强)** ```python # schemas.py from pydantic import BaseModel from datetime import datetime class UserCreate(BaseModel): username: str email: str class UserResponse(BaseModel): id: int username: str email: str created_at: datetime class Config: from_attributes = True # 允许从 ORM 对象读取数据 (Pydantic V2) # orm_mode = True # 如果是 Pydantic V1 ``` **在 `main.py` 中使用:** ```python from schemas import UserCreate, UserResponse @app.post("/users", response_model=UserResponse) async def create_user_v2(user_data: UserCreate): user = await User.create(**user_data.model_dump()) return user ``` **方法 B:使用 `tortoise.contrib.pydantic` 自动生成(快速但灵活性稍低)** ```python from tortoise.contrib.pydantic import pydantic_model_creator User_Pydantic = pydantic_model_creator(User, name="User") UserIn_Pydantic = pydantic_model_creator(User, name="UserIn", exclude_readonly=True) @app.post("/users_auto", response_model=User_Pydantic) async def create_user_auto(user: UserIn_Pydantic): user_obj = await User.create(**user.model_dump()) return user_obj ``` ## **7. 数据库迁移 (Migrations)** 在生产环境中,**不建议**使用 `generate_schemas=True`,因为它每次启动都会尝试重建表结构或无法处理复杂的变更。应该使用迁移工具。 Tortoise-ORM 自带迁移工具 `aerich`。 1. 安装 aerich ```shell pip install aerich ``` 2. 初始化 ```shell aerich init -t main.TORTOISE_ORM ``` (注意:`-t` 后面是你配置字典的路径 `文件路径.变量名`) 3. 生成迁移文件 ```shell aerich migrate ``` 4. 执行迁移 ```shell aerich upgrade ``` ## **关键注意事项** 1. **异步上下文**: 所有的数据库操作(`.create()`, `.filter()`, `.all()`, `.save()`)都必须使用 `await`。 2. 事务处理 ```python async with in_transaction(): ``` 来处理事务。 ```python from tortoise.transactions import in_transaction @app.post("/transfer") async def transfer(): async with in_transaction() as conn: # 在事务内执行操作,使用 connection 参数 user1 = await User.get(id=1).using_db("default") # 或者直接在该上下文中操作 # ... 逻辑 ... ``` (注:具体事务用法请参考最新文档,通常是 `async with in_transaction():` 包裹代码块) 3. **N+1 问题**: 查询关联数据时,务必使用 `.prefetch_related('relation_name')` 来优化性能,避免 N+1 查询问题。 4. **序列化**: Tortoise 模型实例不能直接由 FastAPI (Starlette) 序列化为 JSON,必须转换为字典或使用 Pydantic 模型。