使用 fastapi 初始化乌龟 orm 的问题

问题描述

我在使用 tortoise orm 和 fastapi 时遇到问题

我有以下来自 app.py代码;我跳过了一些行以使其简洁

app.py

from fastapi import FastAPI,HTTPException
from app.models import User_Pydantic,UserIn_Pydantic,Users
from app.utils import cryptoUtil
from app.auth import auth as auth_router
from tortoise.contrib.fastapi import HTTPNotFoundError,register_tortoise


app = FastAPI()

@app.post("/users",response_model=User_Pydantic)
async def create_user(user: UserIn_Pydantic):
    user.password = cryptoUtil.hash_password(user.password)
    user_obj = Users(email=user.email,password=user.password,fullname=user.fullname,status=user.status)
    await user_obj.save()

    return await User_Pydantic.from_tortoise_orm(user_obj)




register_tortoise(
    app,db_url=config.DATABASE_URL,modules={"models": ["app.models"]},generate_schemas=True,add_exception_handlers=True,)


app.include_router(auth_router.router,tags=["Auth"])

if __name__ == '__main__':
    app.run()

这很好用并且能够创建用户

但现在我试图从另一个文件中做同样的事情

auth.py

from fastapi import APIRouter,Depends,HTTPException
from app.auth import crud
from app.utils import cryptoUtil
from app.models import User_Pydantic,Users


router = APIRouter()


@router.post("/auth/register",response_model=User_Pydantic)
async def register(user: UserIn_Pydantic):
    result = await crud.find_exist_user(user.email)
    
    if result:
        raise HTTPException(status_code=404,detail="user already exists!")
    
    user.password = cryptoUtil.hash_password(user.password)
    user_obj = Users(email=user.email,status=user.status)
    await user_obj.save()

    return await User_Pydantic.from_tortoise_orm(user_obj)

但这不起作用,我在 404 错误响应中得到了这个

{
  "detail": "Object does not exist"
}

我认为我遇到的问题是

中的 from_tortoise_orm(user_obj)
return await User_Pydantic.from_tortoise_orm(user_obj)

无法在 auth.py 文件中工作,因为出于某种原因我无法在 app.py 文件之外运行它,这是乌龟初始化的地方

我该怎么做才能解决这个问题? 我遇到的部分问题是如何能够从 app.py 外部 register_tortoise 存在

调用乌龟初始化

更新:

文件夹结构

├── app
│   ├── app.py
│   ├── models.py
│   ├── config.py
│   │
│   ├── auth
│   │   ├── auth.py
│   │   ├── crud.py
│   │      
│   └── utils
│       ├── cryptoUtil.py
│       

解决方法

正如我在评论中所说,您需要插入

Tortoise.init_models(models_list,"models")

在下一行之前

register_tortoise(
    app,db_url=config.DATABASE_URL,modules={"models": ["app.models"]},generate_schemas=True,add_exception_handlers=True,)

当然,您必须根据您的配置更改“models”文件夹和名称。

一开始对我来说也是一个问题,但是下面的github issue解决了这个问题

https://github.com/tortoise/tortoise-orm/issues/444

文档也提供了解释

https://tortoise-orm.readthedocs.io/en/latest/search.html?q=early+init

更新

Tortoise.init_models(models_list,"models")

models_list 是要考虑的模型的路径列表(字符串)。在您的情况下,它将是 app.models

这个想法是在连接到数据库之前初始化并开始准备模型。这是使关系在 pydantic 模型中可用所需的步骤。

这里是 API 文档

https://tortoise-orm.readthedocs.io/en/latest/setup.html?highlight=init#tortoise.Tortoise.init_models