Ir para o conteúdo

Migrações Alembic

Arquivos Referenciados Neste Documento - alembic.ini - env.py - script.py.mako - 001_initial_schema.py - 002_add_decision_type.py - db.py - decision.py

Tabela de Conteúdo

  1. Introdução
  2. Estrutura do Projeto
  3. Componentes Principais
  4. Visão Geral da Arquitetura
  5. Análise Detalhada dos Componentes
  6. Análise de Dependências
  7. Considerações de Desempenho
  8. Guia de Solução de Problemas
  9. Conclusão
  10. Apêndices

Introdução

Este documento explica como o Nexo usa o Alembic para migrações de banco de dados, incluindo o fluxo de trabalho de ponta a ponta para criar, revisar, testar e aplicar alterações de esquema em diferentes ambientes. Ele aborda versionamento, estratégias de compatibilidade descendente, procedimentos de reversão, gerenciamento de dependências, resolução de conflitos e melhores práticas para escrever scripts de migração (transformações de dados, modificações de restrições, gerenciamento de índices). Exemplos referenciam migrações existentes, como a configuração inicial do esquema e adições de tipo de decisão.

Estrutura do Projeto

Os arquivos de configuração e migração do Alembic estão localizados em alembic/. Os elementos principais incluem: - alembic.ini: configuração principal do Alembic - alembic/env.py: configuração do ambiente de execução e tratamento de conexões - alembic/script.py.mako: modelo usado ao gerar novos scripts de migração - alembic/versions/: diretório contendo scripts de migração individuais

graph TB
A["alembic.ini"] --> B["alembic/env.py"]
B --> C["alembic/versions/<migration>.py"]
C --> D["apps/shared/models/*.py"]
B --> E["apps/shared/db.py"]

Fontes do Diagrama - alembic.ini - env.py - 001_initial_schema.py - 002_add_decision_type.py - db.py - decision.py

Fontes da Seção - alembic.ini - env.py - script.py.mako - 001_initial_schema.py - 002_add_decision_type.py - db.py - decision.py

Componentes Principais

  • alembic.ini: define localização de metadados, localizações de scripts e padrões de URL.
  • env.py: carrega configuração, configura o mecanismo/engine do SQLAlchemy e fornece o target_metadata para autogeração.
  • script.py.mako: personaliza cabeçalhos e código dos arquivos de migração gerados.
  • versions/*: cada arquivo representa uma revisão única com funções upgrade() e downgrade().

Responsabilidades principais: - Ciclo de vida da conexão e limites de transação - Autogeração de SQL a partir de alterações de modelo - Rastreamento de versão via tabela alembic_version - Substituições específicas do ambiente via variáveis de configuração

Fontes da Seção - alembic.ini - env.py - script.py.mako

Visão Geral da Arquitetura

O pipeline de migração conecta o Alembic aos modelos SQLAlchemy da aplicação e ao banco de dados por meio do env.py. Ao executar comandos, o Alembic lê o alembic.ini, inicializa o ambiente e executa a operação solicitada contra o banco de dados configurado.

sequenceDiagram
participant Dev as "Desenvolvedor"
participant CLI as "CLI do Alembic"
participant Env as "alembic/env.py"
participant DB as "Banco de Dados"
participant Models as "apps/shared/models"
Dev->>CLI : "alembic revision -m <mensagem>"
CLI->>Env : load_config()
Env-->>CLI : Engine + target_metadata
CLI->>Models : inspeciona modelos (para autogeração)
CLI-->>Dev : gera <hash>_mensagem.py
Dev->>CLI : "alembic upgrade head"
CLI->>Env : connect()
Env->>DB : inicia transação
CLI->>DB : executa etapas de upgrade
DB-->>CLI : sucesso
CLI-->>Dev : revisão aplicada

Fontes do Diagrama - env.py - 001_initial_schema.py - 002_add_decision_type.py - db.py - decision.py

Análise Detalhada dos Componentes

Fluxo de Trabalho de Migração

Processo de ponta a ponta para criar e aplicar migrações:

flowchart TD
Start(["Início"]) --> DefineModel["Atualiza modelos SQLAlchemy"]
DefineModel --> Generate["Gera migração<br/>alembic revision -m '...'"]
Generate --> Review["Revisa script gerado<br/>upgrade()/downgrade()"]
Review --> TestLocal["Testa localmente<br/>alembic downgrade base && alembic upgrade head"]
TestLocal --> Commit["Commita migração e modelos"]
Commit --> Deploy["Implanta em staging/prod"]
Deploy --> Apply["Aplica no banco de dados alvo<br/>alembic upgrade head"]
Apply --> Verify["Verifica esquema e dados"]
Verify --> End(["Concluído"])

[Nenhuma fonte necessária, pois este diagrama mostra o fluxo de trabalho conceitual, não a estrutura de código real]

Criando Novas Migrações

  • Atualize os modelos em apps/shared/models.
  • Gere uma migração: alembic revision -m "mensagem descritiva curta".
  • Se estiver usando autogeração, certifique-se de que o env.py importa todos os modelos para que o Alembic possa detectar alterações.
  • Inspecte o arquivo gerado em alembic/versions/_mensagem.py e ajuste se necessário.

Melhores práticas: - Mantenha as mensagens concisas e significativas. - Prefira múltiplas migrações pequenas em vez de uma alteração grande. - Certifique-se de que tanto upgrade() quanto downgrade() sejam implementados.

Fontes da Seção - env.py - script.py.mako - 001_initial_schema.py - 002_add_decision_type.py

Revisando SQL Gerado

  • Use alembic current para verificar a revisão ativa.
  • Use alembic history para visualizar a cadeia de revisões.
  • Use alembic upgrade --sql head para visualizar o SQL sem executá-lo.
  • Valide se os índices, restrições e operações de dados atendem às expectativas.

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py

Testando Scripts de Migração

Estratégia de teste local recomendada: - Reverta para base: alembic downgrade base - Atualize para head: alembic upgrade head - Repita para confirmar idempotência e correção - Para alterações destrutivas, teste em uma cópia de dados semelhantes à produção

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py

Aplicando Alterações em Diferentes Ambientes

  • Configure URLs ou use variáveis de ambiente para substituir a URL do banco de dados.
  • No CI/CD, execute alembic upgrade head antes de iniciar o serviço.
  • Fixe a revisão esperada nos manifestos de implantação para evitar deriva.

Fontes da Seção - alembic.ini - env.py - db.py

Sistema de Versionamento e Dependências

  • Cada migração tem um ID de revisão único; dependências são declaradas explicitamente quando necessário.
  • Use alembic heads e alembic branches para gerenciar históricos divergentes.
  • Evite ramificações a menos que você precise suportar caminhos de desenvolvimento paralelos; faça merge reescrevendo o histórico com cuidado.

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py

Estratégias de Compatibilidade Descendente

Ao modificar esquemas: - Adicione colunas com valores padrão ou nulas para evitar quebrar o código da aplicação existente. - Introduza novos valores de enum ou campos gradualmente. - Divida alterações em migrações adicionais e de limpeza. - Forneça implementações de downgrade() seguras que revertam alterações sem perda de dados.

Exemplos de referência: - A criação inicial do esquema estabelece tabelas e relacionamentos básicos. - A adição de tipo de decisão demonstra a extensão segura de enums ou estruturas relacionadas.

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py - decision.py

Procedimentos de Reversão

  • Para reverter a última migração: alembic downgrade -1
  • Para reverter para uma revisão específica: alembic downgrade
  • Sempre teste reverter em bancos de dados não de produção primeiro.

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py

Estratégias de Resolução de Conflitos

  • Se dois desenvolvedores ramificam a partir do mesmo pai, resolva mesclando suas migrações em um descendente comum ou reescrevendo o histórico.
  • Use alembic merge para combinar ramificações quando apropriado.
  • Após resolver, verifique com alembic upgrade head e alembic downgrade base.

Fontes da Seção - 001_initial_schema.py - 002_add_decision_type.py

Melhores Práticas para Escrever Scripts de Migração

Transformações de dados: - Atualize em lotes para evitar transações longas. - Use transações explícitas e pontos de confirmação onde suportado. - Preserve a integridade dos dados com a ordenação cuidadosa das operações.

Modificações de restrições: - Remova/recrie restrições apenas quando necessário. - Prefira alterações adicionais (adicione coluna, preencha, então remova a coluna antiga) para minimizar o tempo de inatividade.

Gerenciamento de índices: - Crie índices concorrentemente onde possível para reduzir o tempo de bloqueio. - Remova índices não utilizados em migrações separadas após validação.

Configurações específicas do ambiente: - Use env.py para ler variáveis de ambiente para URL do banco de dados e outras configurações. - Mantenha segredos fora do alembic.ini; prefira injeção em tempo de execução.

Fontes da Seção - env.py - 001_initial_schema.py - 002_add_decision_type.py

Exemplo: Configuração Inicial do Esquema

  • Estabelece tabelas e relacionamentos principais necessários pela aplicação.
  • Serve como a revisão base para alterações subsequentes.

Fontes da Seção - 001_initial_schema.py

Exemplo: Adições de Tipo de Decisão

  • Adiciona ou estende tipos de decisão para suportar a lógica de negócios em evolução.
  • Demonstra a extensão segura de enums ou estruturas relacionadas.

Fontes da Seção - 002_add_decision_type.py - decision.py

Análise de Dependências

Dependências de alto nível entre componentes do Alembic e módulos da aplicação:

graph LR
AlembicINI["alembic.ini"] --> EnvPy["alembic/env.py"]
EnvPy --> DBModule["apps/shared/db.py"]
EnvPy --> Models["apps/shared/models/*.py"]
Versions["alembic/versions/*.py"] --> EnvPy
Versions --> Models

Fontes do Diagrama - alembic.ini - env.py - db.py - decision.py - 001_initial_schema.py - 002_add_decision_type.py

Fontes da Seção - alembic.ini - env.py - db.py - decision.py - 001_initial_schema.py - 002_add_decision_type.py

Considerações de Desempenho

  • Migrações de dados grandes devem ser divididas em lotes para evitar bloqueios longos e pressão de memória.
  • Use a criação concorrente de índices onde suportado para reduzir o tempo de inatividade.
  • Evite operações desnecessárias de ALTER TABLE; faça alterações de esquema em lotes quando possível.
  • Monitore consultas lentas durante backfills e considere índices temporários para acelerá-las.

[Nenhuma fonte necessária, pois esta seção fornece orientação geral]

Guia de Solução de Problemas

Problemas comuns e resoluções: - Modelos faltando na autogeração: certifique-se de que o env.py importa todos os modelos relevantes para que o target_metadata seja completo. - Estado de revisão desatualizado: verifique alembic current e compare com o HEAD do repositório; corrija com alembic stamp se necessário (use com cautela). - Ramificações conflitantes: use alembic merge para reconciliar históricos divergentes. - Erros de transação: divida operações grandes em etapas menores e adicione pontos de confirmação explícitos onde suportado.

Verificações operacionais: - alembic current: mostra a revisão ativa - alembic history: lista revisões e links - alembic upgrade --sql head: visualiza o SQL - alembic downgrade base && alembic upgrade head: teste de ciclo completo

Fontes da Seção - env.py - 001_initial_schema.py - 002_add_decision_type.py

Conclusão

O Alembic fornece uma abordagem robusta e versionada para gerenciar o esquema do banco de dados do Nexo. Seguindo os fluxos de trabalho, melhores práticas e exemplos delineados aqui – especialmente em torno de compatibilidade descendente, testes e configuração específica do ambiente – você pode evoluir o esquema com segurança em desenvolvimento, staging e produção.

[Nenhuma fonte necessária, pois esta seção resume sem analisar arquivos específicos]

Apêndices

Comandos de Referência Rápida

  • Gere migração: alembic revision -m "mensagem"
  • Visualize SQL: alembic upgrade --sql head
  • Aplique a última: alembic upgrade head
  • Reverta a última: alembic downgrade -1
  • Reverta para revisão: alembic downgrade
  • Verifique status: alembic current
  • Liste histórico: alembic history

[Nenhuma fonte necessária, pois esta seção fornece orientação geral]