0

我是 fastAPI 的新手,正在尝试构建一个 todo API。我使用乌龟-ORM。我相信错误是由于在 todo 部分输入空值引起的,尽管我希望它为空或设置为空列表的默认值。这是与错误相关的代码。 主文件

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())

模型.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)

当我尝试创建新用户时,错误开始了。这是来自招摇 UI 的错误

{
  "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"
    }
  ]
}
4

2 回答 2

0

我遇到了类似的问题并找到了解决方案。这里的问题是您的 POST 请求丢失todo_id(不是todo因为数据库自动添加_id到相关字段)。但如果你尝试添加它,你会得到extra fields not permitted. 原因是因为UserIn_pydantic没有这个字段。要解决它,首先尝试通过调用init_models来初始化模型,如下所示:

Tortoise.init_models(['path_to_file_with_models'], 'models')

afterpydantic_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,它将存储在数据库中,您将可以返回它。

至少这对我有用。我希望它也能帮助你。让我知道它是否有帮助。

于 2021-06-15T18:12:55.263 回答
0

问题在错误中说明

“关系“用户”的“todo_id”列中的空值违反了非空约束\n详细信息:失败行包含 (6, bob, bob@email.com, bob123, t, null)。

我在您的表中没有看到任何todo_idUser,但我想这只是由于在 SO 上复制和粘贴的问题。

我没有使用过 TortoiseORM(但我想在它达到稳定版本后使用),但是您是否尝试过将 todo 的定义更改为以下内容?

todo: fields.ForeignKeyNullableRelation[Todo, None] = fields.ForeignKeyField("models.Todo", related_name="todo")

这样,您就可以告诉该字段的类型是ForeignKeyNullableRelation,并且是Todoor None

这是我的猜测,太长了,无法放入评论中,所以我将其发布为答案。

让我知道它是否有效。

于 2020-10-10T15:23:30.360 回答