🧩 Exercícios: Relacionamentos entre Tabelas e Consultas com Join
Spec Backend Com Python E Fastapi • Trilha Progressiva em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 07.1 — Relacionamento One-to-Many com Foreign Key e Relationship
Contexto: Relacionamento One-to-Many com Foreign Key e Relationship no contexto de Relacionamentos entre Tabelas e Consultas com Join.
Requisitos de Execução:
- Modelar entidades
AutoreLivrocom chave estrangeiraautor_ide relacionamento bidirecional.
Resultado Esperado
Autor associado a múltiplos livros com integridade referencial.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_07_1_SeuNome - Envie na tarefa:
Atividade Cap 07 - Relacionamentos entre Tabelas e Consultas com Join
🔑 Gabarito de Código & Solução Comentada
# one_to_many.py
from sqlmodel import SQLModel, Field, Relationship
from typing import List, Optional
class Autor(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
nome: str
livros: List["Livro"] = Relationship(back_populates="autor")
class Livro(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
titulo: str
autor_id: int = Field(foreign_key="autor.id")
autor: Optional[Autor] = Relationship(back_populates="livros")
a = Autor(id=1, nome="Machado de Assis")
l = Livro(id=10, titulo="Dom Casmurro", autor_id=1)
print(f"Livro '{l.titulo}' vinculado ao Autor ID {l.autor_id}")
🔍 Nível 2: Prática
Problema 07.2 — Consulta com Inner Join e Agregação de Contagem
Contexto: Consulta com Inner Join e Agregação de Contagem no contexto de Relacionamentos entre Tabelas e Consultas com Join.
Requisitos de Execução:
- Executar consulta SQLModel combinando duas tabelas para calcular o total de livros por autor.
Resultado Esperado
Consulta Join executada: Autor 'Machado de Assis' possui 1 livro cadastrado.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_07_2_SeuNome - Envie na tarefa:
Atividade Cap 07 - Relacionamentos entre Tabelas e Consultas com Join
🔑 Gabarito de Código & Solução Comentada
# join_query.py
from sqlmodel import select
def gerar_query_join():
# Simulando montagem de query SQLModel
query_str = "SELECT autor.nome, count(livro.id) FROM autor JOIN livro ON autor.id = livro.autor_id GROUP BY autor.nome"
return query_str
print("Query Gerada:", gerar_query_join())
⚡ Nível 3: Integração
Problema 07.3 — Relacionamento Many-to-Many com Tabela Intermediária (Link Table)
Contexto: Relacionamento Many-to-Many com Tabela Intermediária (Link Table) no contexto de Relacionamentos entre Tabelas e Consultas com Join.
Requisitos de Execução:
- Criar relação Many-to-Many entre
UsuarioePerfilusando tabela intermediáriaUsuarioPerfilLink.
Resultado Esperado
Usuário vinculado a múltiplos papéis via tabela de ligação.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_07_3_SeuNome - Envie na tarefa:
Atividade Cap 07 - Relacionamentos entre Tabelas e Consultas com Join
🔑 Gabarito de Código & Solução Comentada
# many_to_many.py
from sqlmodel import SQLModel, Field, Relationship
from typing import List, Optional
class UsuarioPerfilLink(SQLModel, table=True):
usuario_id: Optional[int] = Field(default=None, foreign_key="usuario.id", primary_key=True)
perfil_id: Optional[int] = Field(default=None, foreign_key="perfil.id", primary_key=True)
class Perfil(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
nome: str
usuarios: List["Usuario"] = Relationship(back_populates="perfis", link_model=UsuarioPerfilLink)
class Usuario(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
nome: str
perfis: List[Perfil] = Relationship(back_populates="usuarios", link_model=UsuarioPerfilLink)
p_admin = Perfil(id=1, nome="ROLE_ADMIN")
u = Usuario(id=10, nome="Admin Master", perfis=[p_admin])
print(f"Usuário {u.nome} possui {len(u.perfis)} perfis.")
🏆 Nível 4: Desafio Corporativo
Problema 07.4 — Prevenção do Problema N+1 com Eager Loading (selectinload)
Contexto: Prevenção do Problema N+1 com Eager Loading (selectinload) no contexto de Relacionamentos entre Tabelas e Consultas com Join.
Requisitos de Execução:
- Demonstrar o carregamento antecipado de relações usando
options(selectinload(Autor.livros))em consulta única.
Resultado Esperado
Eager loading configurado: Dados carregados em 1 query sem disparar N consultas adicionais.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_07_4_SeuNome - Envie na tarefa:
Atividade Cap 07 - Relacionamentos entre Tabelas e Consultas com Join
🔑 Gabarito de Código & Solução Comentada
# eager_loading.py
from sqlalchemy.orm import selectinload
from sqlmodel import select
def query_sem_n_mais_um(modelo_pai, relacao):
stmt = select(modelo_pai).options(selectinload(relacao))
print(f"Query Otimizada com Eager Loading para relação {relacao}")
return stmt
print("Configuração de Carregamento Pronta.")