🐳 CAPÍTULO 04: SETUP COMPLETO E ARQUITETURA DUAL-DATABASE


🎯 Objetivos de Aprendizagem

Ao final deste capítulo (estimativa: 2 horas de estudo autoguiado), você será capaz de:

  • 🔹 Configurar o ambiente de desenvolvimento e produção com PostgreSQL 17, SQLite e MongoDB utilizando Docker Compose.
  • 🔹 Aplicar o padrão de Arquitetura Dual-Database: SQLite no desenvolvimento local e PostgreSQL em produção.
  • 🔹 Centralizar strings de conexão e credenciais utilizando variáveis de ambiente com arquivo .env.
  • 🔹 Validar o status de conectividade (Health Check) com SQLAlchemy 2.0 e psycopg2.

Bem-vindo à preparação do seu ambiente. A engenharia de plataformas modernas exige o domínio de diferentes ecossistemas. Você aprenderá a configurar um ambiente Poliglota, suportando tabelas e documentos. 🛡️🧩

🏢 O Cenário Prático (Seu Desafio)

Você lidera a nova célula de Engenharia de Dados da TecProExpress. A equipe de backend desenvolveu um novo painel administrativo, mas eles não conseguem se conectar ao banco de dados porque as portas estão bloqueadas ou os serviços não foram iniciados.

"Seu desafio é criar um laboratório local na sua máquina, garantindo que o PostgreSQL (Relacional) e o MongoDB (NoSQL) rodem simultaneamente em portas diferentes, sem conflitos, provando a saúde do ambiente com testes DDL/DML."


🧠 Fundamentos: Anatomia de um Serviço

Quando instalamos um banco de dados, não instalamos apenas uma "pasta de arquivos". Instalamos um Serviço (Daemon/Background Worker) que fica ouvindo por chamadas.

📊 Comunicação Cliente-Servidor

flowchart LR
    C1["👤 Desenvolvedor<br/>(DBeaver / Compass)"] --> P{"Porta Lógica"}
    P -- 5432 --> S1[("🐘 PostgreSQL Server")]
    P -- 27017 --> S2[("🍃 MongoDB Server")]
    
    style P fill:#ffcc80,stroke:#e65100

🔍 Detalhamento das Conexões:

  • Localhost (127.0.0.1): Endereço que aponta para a sua própria máquina.
  • Porta (Port): O "guichê" de atendimento. Cada banco tem uma porta padrão. Se dois bancos tentarem usar a mesma porta, o serviço cai.

🐘 SETUP RELACIONAL: PostgreSQL e MySQL

1. Download e Instalação

Para SGBDs relacionais pesados, usamos versões nativas LTS (Long Term Support).

  • PostgreSQL 17: Acesse o portal da EnterpriseDB. A porta padrão é a 5432.
  • MySQL 8.4: Acesse o MySQL Installer. A porta padrão é a 3306.

Importante

A Senha Mestra: Durante a instalação, você criará a senha para os superusuários (postgres ou root). O banco de dados é implacável: se você perder essa senha, terá que reinstalar todo o sistema e perderá os dados. Anote em local seguro!

---

🍃 SETUP NOSQL: MongoDB e Cassandra

1. MongoDB (Documentos Flexíveis)

Para dados não estruturados, como os logs das entregas da TecProExpress.

  • Servidor: Baixe o MongoDB Community Server 7.0+. Porta padrão: 27017.
  • Cliente: A instalação já traz o MongoDB Compass, que é a interface gráfica (IDE).

2. Apache Cassandra (Big Data via Docker)

Para lidar com bilhões de registros (ex: dados de GPS dos caminhões), usamos o Cassandra. Para evitar configurar a máquina virtual Java (JVM) na sua máquina, usaremos Docker.

# Passo 1: Baixar e rodar a imagem do Cassandra pelo terminal
docker run --name cassandra-tecpro -p 9042:9042 -d cassandra

📖 Exemplo Guiado: Validando o Setup (DDL -> DML)

A melhor forma de testar se a instalação do PostgreSQL ou MySQL funcionou é criar e povoar uma tabela de testes.

🛠️ Código de Validação

Abra o pgAdmin 4 (ou DBeaver), crie um banco de dados chamado teste_db e execute o script abaixo:

-- PASSO 1: DDL (Criar a estrutura de testes)
CREATE TABLE validacao_ambiente (
    id INT PRIMARY KEY,
    status_servidor VARCHAR(50)
);

-- PASSO 2: DML (Inserir os dados de teste)
INSERT INTO validacao_ambiente (id, status_servidor) VALUES (1, 'Setup Relacional Ativo na TecProExpress!');

-- PASSO 3: Query (Verificar a inserção)
SELECT * FROM validacao_ambiente;

🔍 Detalhamento do Teste:

  • O sucesso na execução deste bloco inteiro garante que a instalação do serviço e a permissão do usuário postgres estão perfeitamente saudáveis.

🛠️ Prática Obrigatória: Conectando a Nave-Mãe

Cenário: O ambiente de testes locais.

  1. Garanta que o Postgres (5432) e o Mongo (27017) estão ativos nos serviços do Windows/Mac.
  2. Abra a interface (pgAdmin/Compass).
  3. Crie as conexões.
  4. No MongoDB Compass, crie uma base de dados (Database) chamada tecpro_nosql e uma coleção chamada teste_conexao. Insira um documento qualquer em JSON para validar.

🏁 Resultado Esperado

Duas janelas verdes na sua máquina atestando que os motores relacional e documental operam simultaneamente sem choque de recursos.


🛢️ Arquitetura Dual-Database: SQLite (Desenvolvimento) ➔ PostgreSQL (Produção)

No desenvolvimento backend corporativo moderno, a aplicação nunca deve depender de um banco de dados específico.

Utilizamos o padrão Dual-Database, onde o desenvolvedor trabalha localmente com SQLite (sem atrito de instalação, em um arquivo .db) e o ambiente de produção roda PostgreSQL 17 (em contêineres Docker de alta performance), conectados pela mesma camada do SQLAlchemy 2.0:

flowchart TD
    APP["🌐 Aplicação Web (Flask / Python)"] ==> ORM["🧱 SQLAlchemy 2.0"]
    
    ORM -->|DATABASE_URL=sqlite:///dev.db| SQLITE["📁 SQLite Local (.db)<br/>• Arquivo único embutido<br/>• Zero atrito no Dia 1 de aula<br/>• Rápido para testes automatizados"]
    ORM -->|DATABASE_URL=postgresql://...| POSTGRES["🐘 PostgreSQL 17 (Docker)<br/>• Servidor de Banco Dedicado<br/>• Alta concorrência e transações ACID<br/>• Produção corporativa escalável"]

    style APP fill:#e3f2fd,stroke:#1565c0
    style ORM fill:#fff8e1,stroke:#f57f17
    style SQLITE fill:#f1f8e9,stroke:#558b2f
    style POSTGRES fill:#e0f2f1,stroke:#00695c

Arquitetura Dual-Database

📊 Tabela Comparativa: SQLite vs PostgreSQL

Característica📁 SQLite (Desenvolvimento)🐘 PostgreSQL (Produção)
ArquiteturaEmbutido (In-Process) dentro da aplicação.Servidor Dedicado (Client-Server) via TCP/IP (Porta 5432).
ArmazenamentoArquivo único .db no diretório do projeto.Tabelas segmentadas em Data Pages (8 KB) gerenciadas pelo motor.
Instalação / SetupZero. Nativo em todas as instalações do Python.Requer instalação de serviço ou contêiner via docker-compose.yml.
ConcorrênciaTravamento (lock) de arquivo em operações de escrita intensivas.Controle de Concorrência Multiversão (MVCC) de altíssima escala.
Connection PoolingDesnecessário (NullPool ou StaticPool).Obrigatório (QueuePool) para reciclar conexões ativas.
Migrações de SchemaExecutadas automaticamente via Alembic.Executadas automaticamente via Alembic.

💻 Ponte Prática: Do SQL Manual ao SQLAlchemy 2.0 ORM

Como o desenvolvedor corporativo gerencia strings de conexão, pools e valida o status dos SGBDs via Python?

🔴 1. A Abordagem Manual (Strings Conectivas Hardcoded e Inseguras)

No modelo amador, a senha do banco fica gravada diretamente no código fonte, sem pooling de conexões e sem tratamento de queda de rede:

# ❌ ABORDAGEM AMADORA: Senhas expostas e sem pool de conexões
import psycopg2

def conectar_manual():
    # Senhas e hosts fixos no código (Falha grave de segurança!)
    conn = psycopg2.connect("dbname=tecpro user=postgres password=root host=localhost port=5432")
    return conn

🟢 2. A Abordagem Profissional (Connection Pool e Health Check com SQLAlchemy)

Com o SQLAlchemy 2.0, usamos create_engine() configurando pool de conexões e testando o Health Check com a consulta padrão text("SELECT 1"):

# ✅ ABORDAGEM PROFISSIONAL: Healthcheck de Conexão e Gestão de Engine
import os
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session

class DatabaseHealthChecker:
    @staticmethod
    def testar_conectividade(database_url: str) -> bool:
        try:
            # pool_pre_ping=True testa se a conexão está viva antes de usá-la
            engine = create_engine(database_url, pool_pre_ping=True, echo=False)
            with engine.connect() as connection:
                resultado = connection.execute(text("SELECT 1")).scalar()
                return resultado == 1
        except Exception as err:
            print(f"  ❌ Falha de conexão ({database_url}): {err}")
            return False

🛠️ Mini-Projeto 04 (BD): Healthchecker Multi-Banco em Python

Objetivo: Criar um script de diagnóstico que valida a conectividade de diferentes engines de dados (SQLite local, SQLite em memória e PostgreSQL simulado).

📋 Pré-requisitos e Instalação

No terminal do seu ambiente virtual (PowerShell ou Bash), instale a biblioteca necessária:

pip install sqlalchemy

💻 Código Completo e Autocontido (miniprojeto_04_healthcheck.py)

Crie o arquivo miniprojeto_04_healthcheck.py e insira o código abaixo integralmente:

"""
Mini-Projeto 04: Healthchecker Multi-Banco em Python
Curso: GTI - Banco de Dados Relacionais e Engenharia de Software
Stack: Python 3.11+ | SQLAlchemy 2.0 | SQLite
"""
import os
from sqlalchemy import create_engine, text

# 1. Componente Diagnóstico de Conectividade
class DatabaseHealthChecker:
    @staticmethod
    def testar_conectividade(database_url: str) -> bool:
        try:
            # pool_pre_ping=True testa a saúde física da conexão antes de liberá-la
            engine = create_engine(database_url, pool_pre_ping=True, echo=False)
            with engine.connect() as connection:
                resultado = connection.execute(text("SELECT 1")).scalar()
                return resultado == 1
        except Exception as err:
            print(f"  ❌ Falha de conexão ({database_url}): {err}")
            return False

# 2. Ponto de Entrada Executável
if __name__ == "__main__":
    print("🔍 AUDITORIA DE SAÚDE DOS SGBDS (HEALTHCHECK) - TECPROEXPRESS")
    print("=" * 65)

    # Dicionário de URLs de conexão dos ambientes da empresa
    ambientes = {
        "1. SQLite Local (Desenvolvimento)": "sqlite:///tecpro_dev.db",
        "2. SQLite Memória (Testes Unitários CI/CD)": "sqlite:///:memory:",
        "3. PostgreSQL Simulado (Produção)": "sqlite:///tecpro_prod_simulado.db"
    }

    for nome_ambiente, url in ambientes.items():
        print(f"\n📡 Testando: {nome_ambiente}...")
        status = DatabaseHealthChecker.testar_conectividade(url)
        if status:
            print("  🟢 STATUS: Conexão Saudável (SELECT 1 OK)")
        else:
            print("  🔴 STATUS: Inacessível (Verificar portas e firewall)")

    print("\n" + "=" * 65)
    print("✅ Diagnóstico de conectividade concluído.")

🚀 Como Executar

Execute o script no terminal:

python miniprojeto_04_healthcheck.py

🖥️ Saída Esperada no Console

🔍 AUDITORIA DE SAÚDE DOS SGBDS (HEALTHCHECK) - TECPROEXPRESS
=================================================================

📡 Testando: 1. SQLite Local (Desenvolvimento)...
  🟢 STATUS: Conexão Saudável (SELECT 1 OK)

📡 Testando: 2. SQLite Memória (Testes Unitários CI/CD)...
  🟢 STATUS: Conexão Saudável (SELECT 1 OK)

📡 Testando: 3. PostgreSQL Simulado (Produção)...
  🟢 STATUS: Conexão Saudável (SELECT 1 OK)

=================================================================
✅ Diagnóstico de conectividade concluído.

💡 Checkpoint de Lógica

Dica

Dica do Especialista: Quando você rodar o Cassandra via Docker, a bandeira -d (detach) no comando permite que o terminal fique livre enquanto o banco roda silenciosamente nos bastidores. A conteinerização é o futuro da arquitetura de dados! 🚀🛡️



🧪 Quiz de Fixação e Autoavaliação — Capítulo 04

1. Por que a Arquitetura Dual-Database adota o SQLite no desenvolvimento local e o PostgreSQL em produção?

  • A) Porque o PostgreSQL não funciona em computadores de desenvolvimento.
  • B) Porque o SQLite permite que os alunos comecem a desenvolver no Dia 1 sem atrito de instalação de servidores (arquivo .db local), e o PostgreSQL no Docker assume em produção para suportar alta concorrência e transações pesadas sem alterar o código da aplicação.
  • C) Porque o SQLite é mais caro que o PostgreSQL.
  • D) Porque o SQLAlchemy só aceita um banco por vez.
💡 Ver Resposta e Justificativa

Resposta Correta: B
Justificativa: O SQLite elimina problemas de setup no Dia 1 de aula; em produção, a mesma aplicação conecta no PostgreSQL apenas trocando a variável DATABASE_URL.


2. Como uma aplicação backend bem projetada (Flask / SQLAlchemy) deve alternar entre o SQLite e o PostgreSQL?

  • A) Colocando comandos if ambiente == 'prod': espalhados em todos os arquivos de rota.
  • B) Lendo a variável de ambiente DATABASE_URL centralizada no arquivo .env (ex: sqlite:///dev.db vs postgresql://user:pass@host:5432/db).
  • C) Reescrevendo todos os modelos e queries do zero.
  • D) Desinstalando o Python e reinstalando o Node.js.
💡 Ver Resposta e Justificativa

Resposta Correta: B
Justificativa: O padrão 12-Factor App determina que a configuração deve ser injetada via variáveis de ambiente, mantendo o código da aplicação 100% agnóstico ao banco.


3. Em um arquivo docker-compose.yml, qual comando mapeia a porta interna 5432 do contêiner PostgreSQL para a porta 5432 do seu computador local?

  • A) volumes: - ./data:/var/lib/postgresql/data
  • B) ports: - '5432:5432'
  • C) environment: - POSTGRES_PASSWORD=root
  • D) restart: always
💡 Ver Resposta e Justificativa

Resposta Correta: B
Justificativa: A diretiva ports: - 'host:container' (ex: '5432:5432') expõe o serviço do contêiner para ferramentas locais como DBeaver e pgAdmin.


🎯 Laboratório Prático

Coloque este conhecimento em prática agora mesmo executando o roteiro autoguiado:
👉 ATIVIDADE 01: SETUP DO AMBIENTE