无效的 Pydantic 字段类型 POST 参数 (FastApi) - Python 3.8

InValid Pydantic Field Type POST parameters (FastApi) - Python 3.8

我正在尝试使用 FastApi + SqlAlchemy,但遇到了参数问题。这是我的 Post 参数导致的错误。我做错了什么?

错误信息

fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'app.models.Post'> is a valid pydantic field type

代码

from fastapi import FastAPI, Response, HTTPException
from fastapi.params import Body, Depends

from sqlalchemy.orm import Session
from starlette import status

from . import models
from .database import engine, get_db
from .models import Post

models.Base.metadata.create_all(bind=engine)
app = FastAPI()


@app.get("/posts")
def get_posts(db: Session = Depends(get_db)):
    posts = db.query(models.Post).all()
    return {"data": posts}


@app.post("/posts", status_code = status.HTTP_201_CREATED)
def create_posts(post: Post, db: Session = Depends(get_db)):
    new_post = models.Post(title=post.title, content=post.content, published=post.published)
    # db.add(new_post)
    # db.commit()
    # db.refresh(new_post)
    return {"data": new_post}

Post 类型

from sqlalchemy import Column, Integer, String, Boolean, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.sql.expression import text
from sqlalchemy.sql.sqltypes import TIMESTAMP

from .database import Base


class Post(Base):
    __tablename__ = "postsalchemy"

    id = Column(Integer, primary_key=True, nullable=False)
    title = Column(String, nullable=False)
    content = Column(String, nullable=False)
    published = Column(Boolean, server_default='TRUE', nullable=False)
    created_at = Column(TIMESTAMP(timezone=True),
                        nullable=False, server_default=text('now()'))

FastAPI 使用 Pydantic 库来验证 HTTP 请求和 HTTP 响应主体。 (顺便说一句 Pydantic 是一个库,它将为您提供针对给定模式的数据结构验证) 为此,您必须创建一个 Pydantic 模型 class 对应于您的 sqlalchemy Post class.

请阅读文档 here 以了解有关响应模型的更多信息。

仅供参考,以下是如何处理您的示例:

from fastapi import FastAPI, Response, HTTPException
from fastapi.params import Body, Depends

from sqlalchemy.orm import Session
from starlette import status

from . import models
from .database import engine, get_db
from .models import Post
from pydantic import BaseModel
from datetime import datetime
from typing import Dict, List

# Define your pydantic response model 
class PostResponse(BaseModel):
    id: int
    title: str
    content: str
    published: bool
    created_at: datetime

models.Base.metadata.create_all(bind=engine)
app = FastAPI()

# Set PostResponse as a response model in the route decorator
@app.get("/posts", response_model=Dict[str, List[PostResponse]])
def get_posts(db: Session = Depends(get_db)):
    posts = db.query(models.Post).all()
    return {"data": posts}


@app.post("/posts", status_code = status.HTTP_201_CREATED, response_model=Dict[str, PostResponse])
def create_posts(post: Post, db: Session = Depends(get_db)):
    new_post = models.Post(title=post.title, content=post.content, published=post.published)
    # db.add(new_post)
    # db.commit()
    # db.refresh(new_post)
    return {"data": new_post}

EXTRA :您可能还对来自 FastAPI 同一作者的 SQLModel 库感兴趣,它是 SQL Alchemy 和 Pydantic 库的组合,基本上可以避免重复(和只声明一次你的模型)