Olá! Vamos continuar a construção do nosso agente de codificação.
Na lição anterior, implementamos um ciclo de feedback crucial, permitindo que o agente analise os resultados dos testes de unidade para corrigir seus próprios erros lógicos. Construímos as verificações de qualidade para o código da aplicação (lint, build, test). Agora, vamos abordar um dos componentes mais sensíveis e de maior risco do seu projeto: as alterações no banco de dados.
O objetivo desta lição é validar scripts de migração de banco de dados gerados para compatibilidade de sintaxe com MariaDB. Diferente do código da aplicação, que é geralmente stateless e pode ser simplesmente substituído, as alterações no banco de dados são stateful e modificam um ativo persistente e compartilhado. Um script de migração incorreto pode levar à corrupção ou perda de dados, tornando esta etapa de validação não apenas uma boa prática, mas uma necessidade crítica.
1. Por que a Validação do Banco de Dados é Diferente
Antes de mergulharmos nas ferramentas, é fundamental entender por que as migrações de banco de dados exigem uma abordagem de validação especializada. O código da aplicação é normalmente implantado substituindo a versão antiga. Se algo der errado, você pode reverter para a versão anterior. Com os bancos de dados, a situação é mais complexa.
CI/CD for database - 2 devops tools for DB versioning and migration | liquibase and flyway
Para começar, vamos assistir a uma breve introdução do vídeo 'CI/CD for database' do canal kanezi, que explica de forma clara a natureza única das alterações de esquema de banco de dados.
Assista à primeira parte do vídeo (00:00:00 - 01:54). Preste atenção especial na distinção que ele faz entre o ciclo de vida do código da aplicação (substituição) e as alterações do banco de dados (migração incremental para preservar o estado/dados existentes).
Como o vídeo destaca, o processo deve ser uma migração incremental. O seu agente não vai gerar um esquema completo e substituir o antigo; ele vai gerar scripts ALTER TABLE, CREATE INDEX, etc., que modificam o esquema existente. Cada um desses scripts representa uma versão.

Para garantir que essas migrações sejam seguras, precisamos de um processo de validação em duas etapas:
- Validação de Sintaxe e Estilo: O SQL gerado é sintaticamente válido para MariaDB e segue as convenções do projeto?
- Validação de Segurança e Semântica: O SQL, embora sintaticamente correto, realiza uma operação destrutiva ou indesejada (como apagar uma tabela ou uma coluna com dados)?
Vamos abordar cada uma dessas validações.
2. Validação de Sintaxe e Estilo com um Linter de SQL
Assim como usamos linters (como ESLint para JavaScript ou Roslyn Analyzers para C#) para garantir a qualidade do código da aplicação, podemos usar um linter para SQL. Um linter de SQL analisa os scripts em busca de erros de sintaxe, inconsistências de estilo e violações de boas práticas, tudo isso sem a necessidade de se conectar a um banco de dados real.
A ferramenta ideal para essa tarefa é o SQLFluff, um linter de SQL altamente configurável e com suporte a múltiplos dialetos.
O vídeo 'Presenting: SQLFluff' da dbt Labs oferece uma excelente introdução à filosofia e funcionalidade da ferramenta. Dado o seu background em desenvolvimento, as analogias com linters de outras linguagens serão bastante familiares.
Assista a estas seções para entender como o SQLFluff se encaixa em nosso fluxo de trabalho: 00:00:00 - 04:56: Esta parte explica por que a consistência de estilo no SQL é crucial para a legibilidade e manutenção, traçando paralelos com ferramentas como flake8 e black do Python. Isso estabelece o 'porquê' por trás do uso de um linter. 04:56 - 07:13: Discute a importância dos dialetos de SQL. Isso é fundamental, pois um script válido para PostgreSQL pode não ser válido para MariaDB. O SQLFluff entende essas diferenças. 11:30 - 13:39: Demonstra como o SQLFluff é usado na prática, incluindo a execução a partir da linha de comando e, mais importante, sua integração em pipelines de CI/CD para falhar uma construção se as regras de lint não forem atendidas. É exatamente assim que nosso agente o usará.
O agente de codificação integrará o SQLFluff como uma etapa de verificação. Após gerar um script de migração, ele executará um comando como:
sqlfluff lint --dialect mariadb /caminho/para/o/script_de_migracao.sql
Se o comando retornar um erro, o agente pode analisar a saída, entender o problema (ex: "Keyword 'select' must be uppercase") e usar essa informação para corrigir o script no ciclo "Generate-Check-Reflect" que vimos na lição anterior.
Para confirmar o suporte do SQLFluff ao seu banco de dados, podemos consultar a documentação.
Dialects Reference — SQLFluff documentation
Vamos verificar rapidamente a documentação oficial do SQLFluff para confirmar o suporte ao MariaDB.
Na página de referência de dialetos, encontre a seção 'MariaDB'. Note que ele existe, herda do dialeto 'MySQL' (o que é esperado) e tem convenções de cotação e casing padrão definidas. Isso nos dá a confiança de que o SQLFluff pode validar corretamente os scripts gerados para o seu ambiente.
3. Validação de Segurança e Semântica com Análise de Esquema
A verificação de sintaxe é essencial, mas não suficiente. Um agente poderia gerar um script perfeitamente sintático que, no entanto, é destrutivo: DROP TABLE Customers;. Precisamos de uma camada de verificação mais inteligente que possa alertar sobre alterações perigosas.
Ferramentas modernas de gerenciamento de esquema de banco de dados, como o Atlas, oferecem essa capacidade. Elas podem simular o efeito de um script de migração em um estado de esquema conhecido e aplicar políticas para bloquear alterações indesejadas.
Setup CI/CD for Versioned Migrations | Atlas Docs
O documento 'Setup CI/CD for Versioned Migrations' do Atlas detalha como a validação avançada de migração pode ser integrada em um fluxo de trabalho de CI.
Leia as seguintes seções para entender o conceito: 'Continuous Integration (CI)': Dê uma olhada no fluxo de trabalho de CI apresentado. O segundo passo, 'Lint', é o nosso foco. 'Linting Migrations': Esta é a seção mais importante. Observe como o Atlas vai além da sintaxe e 'valida migrações em busca de alterações destrutivas, operações incompatíveis com versões anteriores e violações de políticas'. As imagens que mostram comentários em Pull Requests são um exemplo perfeito de como uma ferramenta pode fornecer feedback acionável. 'Push to Registry': Role para baixo nesta seção até ver os exemplos de comando para diferentes bancos de dados. Localize o exemplo para MariaDB. Isso confirma que o Atlas suporta totalmente o seu ambiente.
O Atlas funciona comparando as migrações com um "estado de desenvolvimento" do banco de dados (que pode ser mantido como um conjunto de arquivos SQL que representam o esquema completo). Ao fazer isso, ele pode detectar se uma migração tenta, por exemplo, remover uma coluna que ainda está em uso, uma operação que o SQLFluff (que apenas olha para o arquivo de migração isoladamente) não conseguiria identificar.

4. Integrando a Validação no Fluxo de Trabalho do Agente
Agora, vamos montar o quebra-cabeça. A validação do script de migração se torna outro nó de Check em nosso fluxo de trabalho de agente.
-
Geração (
Generate): O agente analisa a tarefa do Jira e gera o código da aplicação e um script de migração para MariaDB (ex:V202408151030__add_new_feature_flag.sql). -
Validação de Qualidade do Código (
Check App Code): Os testes que implementamos nas lições anteriores (lint, build, unit tests) são executados no código da aplicação. -
Validação da Migração (
Check DB Migration): Este novo nó é executado em paralelo ou em sequência:- Passo 3.1 (Sintaxe/Estilo): Executa
sqlfluff lint --dialect mariadb V2024...sql. - Passo 3.2 (Segurança/Semântica): Executa
atlas migrate lint --dev-url "docker://mariadb/latest/dev" ...para analisar a migração em busca de alterações perigosas.
- Passo 3.1 (Sintaxe/Estilo): Executa
-
Reflexão e Correção (
Reflect & Loop):- Se qualquer uma das verificações de validação falhar, a saída da ferramenta (seja do SQLFluff ou do Atlas) é capturada.
- Um novo prompt é construído, informando o LLM sobre o erro específico:
"O script de migração MariaDB gerado falhou na validação de segurança. A ferramenta Atlas relatou o seguinte erro: 'Destructive change detected: Dropping a column
is_enabledon tablefeaturesmay cause data loss.' Por favor, gere uma nova versão do script que primeiro mova os dados ou adote uma estratégia de migração em duas fases para evitar a perda de dados." - O ciclo se repete até que tanto o código da aplicação quanto o script de migração passem em todas as verificações de qualidade.
-
Criação do Pull Request: Somente quando todas as verificações são aprovadas, o agente prossegue para criar o pull request com os artefatos validados.
Conclusão
Nesta lição, você adicionou uma camada de segurança essencial ao seu agente, garantindo a qualidade e a segurança das alterações de banco de dados que ele propõe.
Principais Pontos:
- As migrações de banco de dados são stateful e incrementais, tornando sua validação mais crítica e complexa do que a do código da aplicação.
- A validação deve ocorrer em duas frentes: sintaxe/estilo e segurança/semântica.
- SQLFluff é uma ferramenta ideal para a validação de sintaxe e estilo, com suporte específico para o dialeto MariaDB.
- Atlas é um exemplo de ferramenta moderna para validação semântica, capaz de detectar alterações destrutivas e violações de políticas de segurança.
- O processo de validação de migração deve ser integrado ao ciclo de auto-correção "Generate-Check-Reflect" do agente, servindo como mais um portão de qualidade antes da criação do pull request.
Com essa etapa concluída, seu agente está muito mais robusto. Ele não apenas gera código funcional, mas também garante que as alterações de banco de dados que o acompanham são seguras e bem formadas.
Na próxima e última lição deste módulo, abordaremos o cenário do "e se mesmo assim algo der errado?". Vamos explorar como definir uma estratégia de rollback caso alguma etapa de garantia de qualidade falhe durante o fluxo, preparando nosso agente para lidar com falhas de maneira graciosa.