📚 Módulo 02: Backend - Setup Inicial, Alembic e Seeders

Para iniciar o desenvolvimento do backend com FastAPI, precisamos estruturar o ecossistema de dependências, configurar as variáveis de conexão com o banco de dados, configurar o motor de migrações Alembic e criar um script Seeder automático para popular nossa base de dados com massa de teste didática.


📦 1. Dependências do Projeto (requirements.txt)

Crie o arquivo requirements.txt na raiz do seu repositório backend:

fastapi==0.110.0
uvicorn[standard]==0.28.0
sqlalchemy[asyncio]==2.0.28
asyncpg==0.29.0
aiosqlite==0.20.0
alembic==1.13.1
pydantic[email]==2.6.4
pyjwt[crypto]==2.8.0
passlib[bcrypt]==1.7.4
python-dotenv==1.0.1

Instale as dependências localmente em seu ambiente virtual com o comando: pip install -r requirements.txt


⚙️ 2. Configurações de Conexão com o Banco de Dados

Criaremos uma classe de configuração dinâmica que lê as variáveis do arquivo .env para determinar se usaremos um banco de dados leve local para desenvolvimento (SQLite assíncrono) ou o banco serverless de produção (Neon PostgreSQL).

Crie o arquivo app/config.py:

import os
from pydantic_settings import BaseSettings
from dotenv import load_dotenv

load_dotenv()

class Settings(BaseSettings):
    # Conexão padrão: SQLite assíncrono local se nenhuma URL for definida
    DATABASE_URL: str = os.getenv(
        "DATABASE_URL", 
        "sqlite+aiosqlite:///./tecloja.db"
    )
    
    # Chave secreta de assinatura do JWT e tempo de expiração
    JWT_SECRET: str = os.getenv("JWT_SECRET", "super-secret-key-of-tecloja-api")
    JWT_ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 120

settings = Settings()

🗄️ 3. Versionamento de Esquema com Alembic

Em grandes projetos, alterar tabelas rodando DDL manual no banco de dados é um antipadrão perigoso. O Alembic rastreia as alterações das classes do SQLAlchemy e gera scripts Python organizados no tempo para subir ou reverter alterações estruturais de forma totalmente automatizada.

Passo 1: Inicializar o Alembic

flowchart TD
    A[SQLAlchemy Models] -->|MetaDados| B(Alembic env.py)
    C[alembic revision --autogenerate] --> B
    B --> D[Script de Migração Python]
    D -->|alembic upgrade head| E[(Banco de Dados Físico)]
    style E fill:#f96,stroke:#333,stroke-width:2px

Na raiz do projeto backend, execute o comando: alembic init alembic

Isso criará uma pasta chamada alembic/ e o arquivo alembic.ini.

Passo 2: Configurar o Target Metadata do SQLAlchemy

Para que o Alembic consiga mapear nossas classes automaticamente, abra o arquivo alembic/env.py e altere as linhas de importação para carregar as nossas entidades e a classe Base:

# Importe a classe Base e os modelos
from app.models.base import Base
from app.models.produto import Categoria, Produto
from app.models.pedido import Cliente, Pedido, ItemPedido
from app.models.usuario import Usuario

# Defina o metadata para autogeração
target_metadata = Base.metadata

Passo 3: Configurar a conexão do banco dinamicamente

Ainda em alembic/env.py, encontre as funções de execução e certifique-se que o Alembic use a URL de conexão definida em nosso arquivo app/config.py:

from app.config import settings

def run_migrations_offline() -> None:
    url = settings.DATABASE_URL
    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )
    # ... resto do código ...

Passo 4: Gerar e Aplicar a Primeira Migração

Para que o Alembic varra nossas entidades e escreva o script SQL de criação de tabelas, execute: alembic revision --autogenerate -m "criar schema inicial tecloja"

Agora, aplique as migrações físicas na base de dados com o comando: alembic upgrade head

O Alembic criará o arquivo de banco tecloja.db com todas as tabelas e chaves estrangeiras modeladas no Módulo 01!


🌱 4. O Data Seeder Automatizado

Nas aulas práticas, é vital que os alunos iniciem os testes com dados válidos preexistentes. Escreveremos um script Python que cria as categorias de tecnologia, insere 5 produtos eletrônicos premium no estoque e cadastra os perfis de usuários com senhas criptografadas.

Crie o arquivo app/seeders/data_seeder.py:

import asyncio
from decimal import Decimal
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from passlib.context import CryptContext
from app.config import settings
from app.models.base import Base
from app.models.produto import Categoria, Produto
from app.models.pedido import Cliente
from app.models.usuario import Usuario

# Criptografia de senhas
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

async def seed_data():
    engine = create_async_engine(settings.DATABASE_URL, echo=True)
    async_session = async_sessionmaker(engine, expire_on_commit=False)

    print("🌱 Iniciando o Seeding de dados da TecLoja 02...")

    async with async_session() as session:
        async with session.begin():
            # 1. Criar Categorias
            smartphones = Categoria(nome="Smartphones")
            notebooks = Categoria(nome="Notebooks")
            acessorios = Categoria(nome="Acessórios")
            
            session.add_all([smartphones, notebooks, acessorios])

            # 2. Criar Produtos Eletrônicos Premium
            p1 = Produto(
                nome="iPhone 15 Pro Max", 
                descricao="Tela Super Retina XDR, chip A17 Pro e câmera de 48MP.", 
                preco=Decimal("9499.00"), 
                estoque=10, 
                categoria=smartphones
            )
            p2 = Produto(
                nome="Galaxy S24 Ultra", 
                descricao="Processador Snapdragon 8 Gen 3 e inteligência artificial Galaxy AI.", 
                preco=Decimal("8499.00"), 
                estoque=8, 
                categoria=smartphones
            )
            p3 = Produto(
                nome="MacBook Pro 16 M3 Max", 
                descricao="Chip M3 Max com CPU de 16 núcleos, GPU de 40 núcleos e 48GB RAM.", 
                preco=Decimal("34999.00"), 
                estoque=3, 
                categoria=notebooks
            )
            p4 = Produto(
                nome="Notebook Dell XPS 13", 
                descricao="Processador Intel Core Ultra 7, 16GB RAM e SSD de 1TB.", 
                preco=Decimal("11999.00"), 
                estoque=5, 
                categoria=notebooks
            )
            p5 = Produto(
                nome="Headphone Sony WH-1000XM5", 
                descricao="Cancelamento de ruído ativo premium e até 30 horas de bateria.", 
                preco=Decimal("2199.00"), 
                estoque=15, 
                categoria=acessorios
            )
            
            session.add_all([p1, p2, p3, p4, p5])

            # 3. Criar Clientes Didáticos
            c1 = Cliente(nome="Maria Silva", email="maria@gmail.com")
            c2 = Cliente(nome="José Souza", email="jose@gmail.com")
            
            session.add_all([c1, c2])

            # 4. Criar Usuários do Sistema com Senhas Criptografadas
            admin = Usuario(
                username="admin@tecloja.com",
                password_hash=pwd_context.hash("admin123"),
                papel="ROLE_ADMIN"
            )
            user = Usuario(
                username="cliente@tecloja.com",
                password_hash=pwd_context.hash("cliente123"),
                papel="ROLE_USER"
            )
            
            session.add_all([admin, user])

        await session.commit()
    
    await engine.dispose()
    print("✨ Seeding concluído com sucesso!")

if __name__ == "__main__":
    asyncio.run(seed_data())

Execute o seeder em seu terminal: python -m app.seeders.data_seeder


✅ Pré-Requisitos deste Módulo

Antes de inicializar as migrações e o seeder, certifique-se de que:


🤔 Por que fizemos assim?


🔍 Checkpoint

  1. Instalação de Dependências: Execute pip install -r requirements.txt e verifique se as bibliotecas foram baixadas sem erros.
  2. Migração Inicial: Execute alembic init alembic, ajuste o arquivo env.py e execute:
    alembic revision --autogenerate -m "criar schema inicial tecloja"
    alembic upgrade head
    

    Confirme se o arquivo físico tecloja.db foi criado no diretório raiz do backend.

  3. Seeder de Testes: Execute o comando de seeding:
    python -m app.seeders.data_seeder
    

    Certifique-se de que a mensagem final "Seeding concluído com sucesso!" é exibida no console do terminal.


⚠️ Erros Comuns

Erro Causa Solução
ModuleNotFoundError: No module named 'app' Tentativa de executar um script diretamente de sua pasta física interna (ex: rodar a partir da pasta /seeders/), quebrando as importações relativas. No terminal, execute sempre os comandos a partir da pasta raiz do repositório backend (tecloja-backend) usando o parâmetro -m (ex: python -m app.seeders.data_seeder).
alembic.util.exc.CommandError: Target database is not up to date O banco de dados físico possui registros ou revisões desalinhadas com o histórico de scripts locais do Alembic. Atualize a versão do banco local rodando alembic upgrade head antes de gerar novas revisões automáticas, ou limpe o banco local deletando o arquivo .db e gerando as revisões do zero.

🏁 Conclusão e Próximos Passos

Incrível! Nossa infraestrutura de banco de dados assíncrona está configurada, versionada com o Alembic e povoada com dados premium de testes didáticos via script Python.

No Módulo 03, entraremos nos pilares de Engenharia de Software. Criaremos a camada de isolamento do contrato utilizando o padrão DTO com schemas do Pydantic v2 e programaremos um manipulador global de exceções para garantir que nenhum erro interno Python seja exposto de forma insegura, retornando sempre mensagens padronizadas em JSON para o frontend.


Voltar para o Sumário