SQLModel объединяет SQLAlchemy и Pydantic — одна модель для БД и API.
Установка
pip install sqlmodel
Модели
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): # таблица в БД
id: Optional[int] = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
class TaskCreate(TaskBase): # для POST запроса
pass
class TaskResponse(TaskBase): # для ответа API
id: int
created_at: datetime
База данных
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()
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!