📊 Capítulo 07: Relacionamentos & Joins no SQLModel
Especialização Backend com Python & FastAPI
🗺️ Mapeamento 1:N e N:N com SQLModel
erDiagram
USUARIO ||--o{ PEDIDO : "possui (1:N)"
PEDIDO ||--|{ ITEM_PEDIDO : "contém (1:N)"
ITEM_PEDIDO }|--|| PRODUTO : "referencia (N:1)"
USUARIO {
int id PK
string nome
string email UK
}
PEDIDO {
int id PK
int usuario_id FK
datetime criado_em
string status
}
ITEM_PEDIDO {
int id PK
int pedido_id FK
int produto_id FK
int quantidade
float preco_unitario
}
🎯 Slide 1: Definindo Relações com Relationship()
class Usuario(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
nome: str
pedidos: List["Pedido"] = Relationship(back_populates="usuario")
class Pedido(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
usuario_id: int = Field(foreign_key="usuario.id")
usuario: Optional[Usuario] = Relationship(back_populates="pedidos")
🎯 Slide 2: Consultas com selectinload() no Async
- Carregamento Seguro de Relações: No SQLAlchemy/SQLModel assíncrono, nunca acesse atributos relacionais sem carregá-los explicitamente: ```python from sqlalchemy.orm import selectinload
statement = ( select(Pedido) .where(Pedido.id == pedido_id) .options(selectinload(Pedido.usuario)) # Carrega o usuário junto sem travar o async! ) result = await session.exec(statement) pedido = result.first()
---
## 🎯 Slide 3: Consultas com JOINs Explícitos
```python
# Consulta com JOIN e agregações
statement = (
select(Usuario.nome, func.count(Pedido.id).label("total_pedidos"))
.join(Pedido, Usuario.id == Pedido.usuario_id)
.group_by(Usuario.id)
)
Slide 1 de 1
Atalhos: ← → Navegar • Espaço Avançar • F Tela Cheia • Home Início • End Fim