问题描述
我是fastAPI的新手,正在尝试构建todo API。我使用Tortoise-ORM。我相信该错误是由于在todo部分输入空值引起的,尽管我希望它为空或设置为默认值(这是一个空列表)。这是与错误相关的代码。 main.py
from typing import List
import os
from fastapi import FastAPI,Depends,HTTPException,status
from models import User,Todo,User_pydantic,UserIn_pydantic,Todo_pydantic,TodoIn_pydantic
from tortoise.contrib.fastapi import register_tortoise,HTTPNotFoundError
app = FastAPI()
@app.post("/users/",response_model=User_pydantic)
async def create_user(user: UserIn_pydantic):
user_obj = await User.create(**user.dict(exclude_unset=True))
return await User_pydantic.from_tortoise_orm(user_obj)
@app.get("/users/",response_model=List[User_pydantic])
async def read_all_users():
return await User_pydantic.from_queryset(User.all())
models.py
from tortoise.models import Model
from tortoise import fields
from tortoise.contrib.pydantic import pydantic_model_creator
class Todo(Model):
id = fields.IntField(pk=True)
title = fields.CharField(500)
description = fields.TextField(null=True)
Todo_pydantic = pydantic_model_creator(Todo,name="Todo")
TodoIn_pydantic = pydantic_model_creator(Todo,name="TodoIn",exclude_readonly=True)
class User(Model):
id = fields.IntField(pk=True)
username = fields.CharField(500,unique=True)
email = fields.CharField(100,unique=True)
password = fields.CharField(100)
is_active = fields.BooleanField(default=True)
todo: fields.ForeignKeyNullableRelation[Todo] = fields.ForeignKeyField("models.Todo",related_name="todo")
class PydanticMeta:
exclude = ["is_active","todo"]
User_pydantic = pydantic_model_creator(User,name="User")
UserIn_pydantic = pydantic_model_creator(User,name="UserIn",exclude_readonly=True)
{
"detail": [
{
"loc": [],"msg": "null value in column \"todo_id\" of relation \"user\" violates not-null constraint\nDETAIL: Failing row contains (6,bob,bob@email.com,bob123,t,null).","type": "IntegrityError"
}
]
}
解决方法
问题在错误中指出
“关系“用户”的列“ todo_id”中的空值违反 非空约束\ n详细信息:失败行包含(6,bob, bob@email.com,bob123,t,null)。
在您的todo_id
表中没有看到任何User
列,但是我想这只是由于在SO上复制和粘贴存在问题。
我还没有使用过TortoiseORM(但是我想在它达到稳定版本后使用它),但是您是否尝试过将todo的定义更改为以下内容?
todo: fields.ForeignKeyNullableRelation[Todo,None] = fields.ForeignKeyField("models.Todo",related_name="todo")
通过这种方式,您可以知道该字段的类型为ForeignKeyNullableRelation
,并且为Todo
或None
。
这是我的猜测,太长了,无法放入评论中,因此我将其发布为答案。
让我知道它是否有效。
,我遇到了类似的问题并找到了解决方案。这里的问题是您的 POST 请求缺少 todo_id
(不是 todo
,因为数据库会自动将 _id
添加到相关字段)。但是如果您尝试添加它,您将获得 extra fields not permitted
。
原因是因为 UserIn_pydantic
没有这个字段。要解决它,首先尝试通过调用 init_models 来初始化您的模型:
Tortoise.init_models(['path_to_file_with_models'],'models')
pydantic_model_creator
之后应该做剩下的事情,它适用于大多数情况。如果没有,那么只需简单地覆盖它:
UserIn_pydantic = pydantic_model_creator(User,name="UserIn",exclude_readonly=True)
class UsersIn_PydanticWithRelation(UsersIn_Pydantic):
todo_id: int
User_pydantic = pydantic_model_creator(User,name="User")
class Users_PydanticWithRelation(Users_Pydantic):
client_id: int
并在您的 main.py 中替换您的类型注释。这样您就可以 POST todo_id
,它将存储在数据库中,您可以返回它。
至少这对我有用。我希望它也能帮助你。如果有帮助,请告诉我。