Script Valley
FastAPI: Build Production Python APIs
Database Integration with SQLAlchemyLesson 3.3

How to perform CRUD operations with SQLAlchemy in FastAPI

session.add, session.commit, session.refresh, session.query, filter, first, all, session.delete, CRUD layer pattern, separating DB logic from routes

CRUD Operations with SQLAlchemy

Keep database logic in a separate crud.py file. Routes stay thin — they call CRUD functions and convert results to Pydantic schemas.

crud.py

from sqlalchemy.orm import Session
from . import models, schemas

def get_user(db: Session, user_id: int):
    return db.query(models.User).filter(
        models.User.id == user_id
    ).first()

def get_users(db: Session, skip: int = 0, limit: int = 10):
    return db.query(models.User).offset(skip).limit(limit).all()

def create_user(db: Session, user: schemas.UserCreate):
    hashed = fake_hash(user.password)
    db_user = models.User(email=user.email, hashed_password=hashed)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)  # loads auto-generated id
    return db_user

def delete_user(db: Session, user_id: int):
    user = get_user(db, user_id)
    if user:
        db.delete(user)
        db.commit()
    return user

Route using CRUD

@app.get("/users/{user_id}", response_model=schemas.UserOut)
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = crud.get_user(db, user_id)
    if not user:
        raise HTTPException(404, "User not found")
    return user

Always call db.refresh(db_user) after commit to load server-generated values like auto-increment IDs and default timestamps.

Up next

How to use Alembic for database migrations in FastAPI projects

Sign in to track progress