I am attempting to use FastApi SqlAlchemy And am having an issue with Parameters. This is the Error my Post parameter is causing. What am i doing wrong?
ERROR MESSAGE
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'app.models.Post'> is a valid pydantic field type
Code
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 Type
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()'))
CodePudding user response:
FastAPI uses Pydantic library to validate both HTTP request and HTTP response body. ( BTW Pydantic is a library that will provide you validation of data structure against a given schema )
For that purpose, you must create a Pydantic Model class that corresponds to your sqlalchemy Post class.
Please read the docs here to learn more about response model.
FYI, here is how to do with your example :
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 : You might be also interested in SQLModel library which is from the same author of FastAPI and is a combination between SQL Alchemy and Pydantic library and basically allow you to avoid duplication (and declare your model only once)
