๐Ÿ“ Fastapi

SQLModel CRUD in FastAPI

P
Author
PyLand Team
๐Ÿ“…
Published
30.06.2026
โฑ๏ธ
Reading time
1 min
๐Ÿ‘๏ธ
Views
313
๐ŸŒณ
Level
Advanced

SQLModel combines SQLAlchemy and Pydantic โ€” a single model for both the database and the API.

Installation

pip install sqlmodel

Models

from sqlmodel import SQLModel, Field
from typing import Optional
from datetime import datetime

class TaskBase(SQLModel):
    title: str = Field(min_length=1, max_length=200)
    status: str = Field(default="todo")
    priority: int = Field(default=1, ge=1, le=3)

class Task(TaskBase, table=True):           # database table
    id: Optional[int] = Field(default=None, primary_key=True)
    created_at: datetime = Field(default_factory=datetime.utcnow)

class TaskCreate(TaskBase):                 # for POST requests
    pass

class TaskResponse(TaskBase):              # for API responses
    id: int
    created_at: datetime

Database

from sqlmodel import create_engine, Session, SQLModel

DATABASE_URL = "sqlite:///./db.sqlite3"
engine = create_engine(DATABASE_URL)

def create_tables():
    SQLModel.metadata.create_all(engine)

def get_session():
    with Session(engine) as session:
        yield session

CRUD endpoints

from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Session, select

app = FastAPI()

@app.post("/tasks/", response_model=TaskResponse, status_code=201)
def create_task(task: TaskCreate, session: Session = Depends(get_session)):
    db_task = Task.model_validate(task)
    session.add(db_task)
    session.commit()
    session.refresh(db_task)
    return db_task

@app.get("/tasks/", response_model=list[TaskResponse])
def list_tasks(session: Session = Depends(get_session)):
    tasks = session.exec(select(Task)).all()
    return tasks

@app.get("/tasks/{task_id}", response_model=TaskResponse)
def get_task(task_id: int, session: Session = Depends(get_session)):
    task = session.get(Task, task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    return task

@app.patch("/tasks/{task_id}", response_model=TaskResponse)
def update_task(task_id: int, task_update: TaskCreate, session: Session = Depends(get_session)):
    task = session.get(Task, task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    task_data = task_update.model_dump(exclude_unset=True)
    task.sqlmodel_update(task_data)
    session.add(task)
    session.commit()
    session.refresh(task)
    return task

@app.delete("/tasks/{task_id}", status_code=204)
def delete_task(task_id: int, session: Session = Depends(get_session)):
    task = session.get(Task, task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    session.delete(task)
    session.commit()

Your reaction to the article

๐Ÿ’ฌ Comments (0)

๐Ÿ” Sign in to leave a comment
๐Ÿšช Login
๐Ÿ’ญ

No comments yet

Be the first to share your opinion about this article!

๐Ÿ”— Similar

Similar articles

Continue learning with these materials

๐Ÿ“

Middleware and CORS in FastAPI

Middleware processes requests and responses around FastAPI routes, while CORS controls which browser origins may...

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 330
๐Ÿ“

HTTPException in FastAPI

Covered topics: Basic Usage, Status Codes, Error Details, Custom Headers.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 298
๐Ÿ“

Dependency Injection in FastAPI

Depends โ€” FastAPI's dependency injection system for reusing code across endpoints.

๐Ÿ“… 30.06.2026 ๐Ÿ‘๏ธ 304
๐ŸŽ“ Continue learning

Courses that cover this material

Visit the course to apply this material in practice.

FastAPI: From First Route to an AI-Powered Site Open course curriculum