问题描述
我在使用 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 文档