Я работаю над веб-сервером, созданным с использованием FastAPI версии 0.111.0 и SQLModel версии 0.0.18.
Когда я вызываю конечную точку POST с частичными данными или с ключами, которые я не указываю в своем классе, это не вызывает необрабатываемую сущность или ошибку неправильного запроса. Я использую метод POST только для вставки данных, а не для их обновления. Для обновления объекта я использую отдельный запрос PUT.
Вот моя модель:
from sqlmodel import SQLModel, Field
class Job(SQLModel, table=True):
job_id: int = Field(primary_key=True)
title: str
start_time: str
end_time: str | None = None
pipeline_id: int = Field(foreign_key = "pipeline.pipeline_id")
prj_path: str
branch_tag: str
user: str
status: str
log: str = ""
result: str = ""
и вот контроллер:
from fastapi import APIRouter
from models.job import Job
job_router = APIRouter(prefix = "/job", tags=["Jobs"])
@job_router.post("/", status_code=201, response_model=Job)
async def add_job(job: Job):
job = await c.insert_job(job)
return job
c.insert_job(job)
— это место, где я сохраняю объект в базе данных, а job_router
импортируется в основной файл с помощью приложения FastAPI:
from fastapi import FastAPI
from routers.job import job_router
app = FastAPI()
app.include_router(job_router)
Даже если в автоматически созданной документации указано, что есть некоторые обязательные поля, как показано здесь:
мастер-класс по чванству
если я отправляю запрос с телом типа { "job_id": 0 }
или даже { "job_id": 0, "test": "test" }
, он проходит, не вызывая ничего, как показано на следующем изображении (здесь я возвращаю полученный частичный объект вместо добавления его в базу данных, потому что это вызовет ошибку поля без значения по умолчанию):
возвращенный объект
Используйте эту модель для проверки ответа
from pydantic import BaseModel
from typing import Optional
class JobRead(BaseModel):
job_id: int
title: str
start_time: str
end_time: Optional[str] = Field(default=None)
pipeline_id: int
prj_path: str
branch_tag: str
user: str
status: str
log: Optional[str] = Field(default = "")
result: Optional[str] = Field(default = "")
И вы можете использовать проверку Pydantic о проверке https://docs.pydantic.dev/latest/#why-use-pydantic
или используйте Depends() с моделью Pydantic
from fastapi import APIRouter
from models.job import Job
job_router = APIRouter(prefix = "/job", tags=["Jobs"])
@job_router.post("/", status_code=201, response_model=Job)
async def add_job(job: Job = Depends()):
job = await c.insert_job(job)
return job
про Зависит https://fastapi.tiangolo.com/tutorial/dependents/
Ваш код не работает, потому что вы используете класс sqlmodel. BaseModel — это класс pydantic, имеющий проверку. Извините за мой английский, пожалуйста)
Вам нужно написать классы для sql, проверки и т. д.
Спасибо, это сработало! Но я не понимаю, почему использование класса, расширяющего BaseModel, не работает, а использование BaseModel напрямую работает...