💻 Exemplos: Capítulo 06: Sessões Assíncronas (AsyncSession) e Operações CRUD
Especialização em Backend com Python & FastAPI • Demonstrações Práticas Compiláveis
💻 Exemplo 1 — Dependência de Sessão Assíncrona Integrada ao FastAPI
from typing import Annotated, AsyncIterator
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import SQLModel, Field, select
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
class Produto(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
nome: str
preco: float
engine = create_async_engine("sqlite+aiosqlite:///./catalogo.db")
app = FastAPI()
async def get_session() -> AsyncIterator[AsyncSession]:
async with AsyncSession(engine) as session:
yield session
SessionDep = Annotated[AsyncSession, Depends(get_session)]
@app.on_event("startup")
async def on_startup() -> None:
async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)
@app.post("/produtos", status_code=201)
async def criar_produto(nome: str, preco: float, session: SessionDep) -> Produto:
produto = Produto(nome=nome, preco=preco)
session.add(produto)
await session.commit()
await session.refresh(produto)
return produto
@app.get("/produtos/{produto_id}")
async def obter_produto(produto_id: int, session: SessionDep) -> Produto:
produto = await session.get(Produto, produto_id)
if produto is None:
raise HTTPException(404, "Produto não encontrado")
return produto
💻 Exemplo 2 — Consulta Filtrada e Atualização Parcial (PATCH)
from typing import Optional
from sqlmodel import SQLModel, select
from sqlmodel.ext.asyncio.session import AsyncSession
class ProdutoUpdate(SQLModel):
nome: Optional[str] = None
preco: Optional[float] = None
async def listar_por_faixa_preco(session: AsyncSession, minimo: float, maximo: float):
stmt = select(Produto).where(Produto.preco.between(minimo, maximo)).order_by(Produto.preco)
resultado = await session.exec(stmt)
return resultado.all()
async def atualizar_parcial(session: AsyncSession, produto_id: int, dados: ProdutoUpdate) -> Produto | None:
produto = await session.get(Produto, produto_id)
if produto is None:
return None
for campo, valor in dados.model_dump(exclude_unset=True).items():
setattr(produto, campo, valor)
session.add(produto)
await session.commit()
await session.refresh(produto)
return produto
💻 Exemplo 3 — Soft Delete Assíncrono com Auditoria
from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field
from sqlmodel.ext.asyncio.session import AsyncSession
class Pedido(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
descricao: str
is_deleted: bool = Field(default=False)
deleted_at: Optional[datetime] = None
async def soft_delete_pedido(session: AsyncSession, pedido_id: int) -> bool:
pedido = await session.get(Pedido, pedido_id)
if pedido is None or pedido.is_deleted:
return False
pedido.is_deleted = True
pedido.deleted_at = datetime.utcnow()
session.add(pedido)
await session.commit()
return True