This article clarifies the differences between Pydantic models and SQLAlchemy models in a FastAPI application.
This article clarifies the differences between a schema (Pydantic model) and an ORM (SQLAlchemy model) by demonstrating their roles within a FastAPI application. The Pydantic model validates incoming requests and outgoing responses, while the SQLAlchemy model establishes the database table structure.
Below is an initial code snippet showing the essential imports and setup for the FastAPI application:
Copy
Ask AI
from random import randrangeimport psycopg2from psycopg2.extras import RealDictCursorimport timefrom sqlalchemy.orm import Sessionfrom sqlalchemy.sql.functions import modefrom fastapi import FastAPI, Depends, statusfrom pydantic import BaseModelfrom . import modelsfrom .database import engine, get_dbmodels.Base.metadata.create_all(bind=engine)app = FastAPI()class Post(BaseModel): title: str content: str published: bool = Truewhile True: # This loop demonstrates an example of a service running continuously. pass
The following log output confirms that the application starts successfully and provides examples of handling PUT requests:
Copy
Ask AI
INFO: Application startup complete.INFO: 127.0.0.1:54950 - "PUT /posts/1 HTTP/1.1" 200 OKINFO: 127.0.0.1:65135 - "PUT /posts/12342324 HTTP/1.1" 404 Not Found
Remember that the Pydantic model is primarily used for request/response data validation, while the SQLAlchemy model is used to define the persistent data structure of your database.
The following code snippet demonstrates how path operations use the Pydantic model to validate incoming data for fetching and creating posts:
Copy
Ask AI
@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)): # The code to insert the post into the database has been omitted for brevity. pass
The Pydantic model named Post validates that any request to create a new post contains the fields title, content, and (optionally) a published flag. This strict validation approach helps protect the API from malformed data and ensures consistency in the data exchange.
The diagram below further illustrates how the SQLAlchemy model defines the columns of the “posts” table and its role in handling operations such as querying, creating, deleting, and updating database entries:
In summary, the Pydantic model (schema) ensures that both requests and responses comply with the expected data structures, while the SQLAlchemy model provides a detailed blueprint of the database table structure. Although adopting Pydantic models is technically optional, it is a best practice for building robust and secure APIs by enforcing strict data validation.
By carefully separating concerns—using Pydantic for data validation and SQLAlchemy for database interactions—developers can build maintainable and secure APIs that efficiently manage data flow between clients and servers.