tezvyn:

Explain SQLAlchemy ORM vs Pydantic models in FastAPI

AI-drafted, machine-checkedSource: fastapi.tiangolo.combeginner
Explain SQLAlchemy ORM vs Pydantic models in FastAPI

This tests separation of database schema from API contracts. A strong answer distinguishes SQLAlchemy table rows from Pydantic validation and OpenAPI generation, and notes that create schemas exclude auto-generated IDs.

WHAT THIS TESTS: This question probes whether you understand layer separation in a modern Python web stack. The interviewer wants to see that you recognize SQLAlchemy belongs to the persistence layer and Pydantic belongs to the API contract layer, and that conflating them creates coupling, security gaps, and documentation bugs.

A GOOD ANSWER COVERS: First, the SQLAlchemy ORM model is a declarative mapping to a database table; it handles columns, relationships, indexes, and session-bound object state. Second, the Pydantic model is a data validation and serialization schema; it enforces types, constraints, and default values at the HTTP boundary and automatically generates OpenAPI documentation for the FastAPI UI. Third, a dedicated create schema is used because the client should not supply server-generated fields such as primary keys, created_at timestamps, or computed columns; the endpoint accepts the Pydantic create model, maps its fields to a new SQLAlchemy instance, commits the session, and returns a public Pydantic model that includes the generated fields. Fourth, keeping them separate lets the database schema evolve independently from the API contract; you can rename a column or add a foreign key without breaking client-facing payloads.

COMMON WRONG ANSWERS: Claiming that SQLAlchemy and Pydantic are interchangeable or that one should be eliminated to reduce duplication. Suggesting that the ORM model can be used directly as the request body type, which leaks database internals and prevents omitting sensitive or generated fields. Asserting that code duplication is always bad without acknowledging that accidental coupling is worse. Confusing SQLModel with raw SQLAlchemy and failing to explain why FastAPI documentation relies on Pydantic types.

LIKELY FOLLOW-UPS: How would you handle a case where the database column names differ from the API field names? What if you need to expose a field in the API that is computed from multiple columns? How does SQLModel change this picture? Can you use Pydantic v2 computed fields to bridge the gap? How do you handle circular dependencies between ORM relationships and Pydantic nested models?

ONE CONCRETE EXAMPLE: Imagine a Hero table with id, name, secret_name, and age. The SQLAlchemy model maps all four columns. The Pydantic HeroCreate model includes only name and age because secret_name is internal and id is auto-incremented. The POST endpoint accepts HeroCreate, instantiates a SQLAlchemy Hero, adds it to the session, commits, and returns a HeroPublic model containing id, name, and age while omitting secret_name. This pattern prevents the client from forging an ID or reading a secret identity.

Source: fastapi.tiangolo.com

Read the original → fastapi.tiangolo.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.