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:

  1. Modelar entidades Autor e Livro com chave estrangeira autor_id e relacionamento bidirecional.

Resultado Esperado

Autor associado a múltiplos livros com integridade referencial.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_1_SeuNome
  2. 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:

  1. 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)

  1. Salve o arquivo como: Atividade_07_2_SeuNome
  2. 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

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:

  1. Criar relação Many-to-Many entre Usuario e Perfil usando tabela intermediária UsuarioPerfilLink.

Resultado Esperado

Usuário vinculado a múltiplos papéis via tabela de ligação.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_3_SeuNome
  2. 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:

  1. 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)

  1. Salve o arquivo como: Atividade_07_4_SeuNome
  2. 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.")