Flyway e versionamento de bases de dados

O intuito desse post é apresentar a ferramenta Flyway, uma ferramenta opensource para a migração de bases de dados.
Não será apresentada a instalação e utilização do mesmo, mas sim os conceitos envolvidos e sua importância. A instalação e utilização serão abordadas em um próximo tópico. Vejamos então do que se trata o versionamento de bases de dados.
Versionamento de bases de dados
É muito comum que as aplicações, sejam elas web, desktop ou mobile façam uso de bases de dados para armazenar informações inseridas pelos usuários. Essas bases de dados podem ser tanto relacionais, também conhecidas com SQL, quanto não relacionais (ou NoSQL). No entanto, as primeiras ainda são utilizadas com maior frequencia, por isso, nosso foco será nelas.
As bases de dados relacionais mantém os dados armazenados em estruturas denominadas tabelas, as quais contém linhas e colunas. As colunas tem um nome, que identifica o tipo de informação que será armazenada, já as linhas contém os dados de um determinado registro. Para simplificar, vamos imaginar que queremos armazenar o nome, o CPF e o ano de nascimento de nossos usuários. Nesse caso, poderíamos ter uma tabela pessoa (porque armazena informações de pessoas), do seguinte modo:
CPF | Nome | Ano de nascimento |
---|---|---|
111.222.333-44 | Aristóteles | 384 a.C. |
333.111.222-44 | Platão | 427 a.C. |
222.111.333-44 | Sócrates | 470 a.C. |
Observe que nesse caso, nossas colunas são respectivamente CPF, Nome e Ano de nascimento. Já nas linhas, temos os valores dessas três colunas para uma determinada pessoa. Por exemplo, na primeira linha temos essas informaçẽos para o Aristóteles e na última para o Sócrates.
Se você estiver usando alguma linguagem orientada a objetos, como por exemplo Java, teria uma classe semelhante a essa:
Agora imagine que você precisa adicionar mais um atributo nessa classe, como por exemplo o endereço da pessoa. Essa alteração fará com que seja necessário criar mais uma coluna na tabela. Nesse caso você deve rodar um script no banco de dados para inserí-la. O script poderia ser semelhante a esse:
ALTER TABLE pessoa ADD COLUMN endereco character varying(100);
Chamamos esse processo de atualização do base de dados de migração (ou em inglês, migration). Essa migração, idealmente, deve ser rodada no momento que você atualizar a versão da sua aplicação, para que ele possa ser executado sem que ocorram erros.
Quando você tem o controle do banco de dados, e da aplicação, é até possível fazer esse processo "manualmente". Mas você acaba ficando sujeito a falhas e dificuldades no processo.
Vamos analisar alguns possíveis problemas dessa abordagem:
Falta de atualização da base de dados, ou atualização incompleta
Se você não realizar a migração da sua base de dados, ou esquecer de rodar algum comando, como por exemplo a criação de uma tabela, provavelmente sua aplicação apresentará erros ao usuário, por não conseguir encontrar as tabelas e/ou campos novos.
Falta de controle do estado da base
Ao realizar migrações de maneira manual, não há necessariamente um modo padronizado de organizar quais scripts SQL foram exeutados em uma determinada atualização de versão da aplicação. Além disso, não existe a princípio nenhum registro de quando foram executadas as migrações, e nem quem realizou a operação. Com isso, ao permitir que migrações sejam realizadas por desenvolvedores ou DBAs, não há a priori um registro das operações executadas na base.
Falta de automatização da migração
Imagine que sua aplicação é instalada localmente por cada cliente. Se não houver um processo automático, ou automatizado de atualização da aplicação, que inclua a execução das migrações necessárias da base de dados, o cliente pode cometer erros nesse processo, que levem a problemas na aplicação.
Do mesmo modo pode ocorrer nas próprias equipes de desenvolvimento. Se cada desenvolvedor utilizar um ambiente local de desenvolvimento, ele terá que rodar manualmente as novas migrações para que o sistema possa ser executado de maneira correta no seu ambiente, estando sujeito aos mesmos erros aos quais os clientes estão.
Falta de rollback automático
Considere a situação onde mais de um script SQL tem que ser rodado para preparar a base de dados para uma nova versão do sistema. Supondo que você execute os scripts individualmente, e somente o último script dê problema, você talvez terá que dar rollback nos scripts anteriores, até corrigir o problema encontrado.
Nesse caso, você não dispõe de um modo automático de executar o rollback e terá que fazer esse processo manualmente, o que está sujeito a erros.
Versionamento de dados automático com o Flyway
Feitas essas considerações sobre os problemas oriundos da falta de versionamento da base de dados, e da falta de automatização desse processo, espero que tenha ficado claro para você a vantagem de utilizar o Flyway, que cumpre exatamente esses dois papéis.
Vamos entender agora como funciona o Flyway. Nessa ferramenta, cada script SQL é considerada uma migração, ou migration. O Flyway cria uma tabela na própria base de dados para gerenciar quais migrações já foram aplicadas, e armazena algumas informações sobre a migração, como por exemplo quando foi executada, o usuário que executou, o nome do arquivo do script, entre outras.
Veja um exemplo fictício de uma tabela do Flyway com 3 migrações executadas:
installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | Banco original | BASELINE | Banco original | flyway_user | 2016-10-20 17:15:00.384658 | 0 | t | |
2 | 1 | adicao-cartao-credito | SQL | V1__adicao-cartao-credito-PROD.sql | 1920168101 | flyway_user | 2016-10-21 10:41:40.938276 | 1834 | t |
3 | 2 | alterar-tipo-dado-numero-cartao | SQL | V2__alterar-tipo-dado-numero-cartao-PROD.sql | 1996158423 | flyway_user | 2016-10-26 09:48:43.626821 | 51 | t |
Nesse exemplo, podemos perceber que cada linha da tabela representa uma migração. A coluna installed_rank
mostra a ordem na qual as migrações foram executadas, ou "instaladas" na base de dados. Já a coluna version
representa a versão da base de dados que foi gerada com a aplicação da migração. description
é a descrição da(s) alteração(ões) realizadas pela migração (podemos definir esse nome como veremos em um post futuro).
A coluna type
define o tipo de migração que foi executada. Podemos perceber que no exemplo, existem dois tipos: baseline
e SQL
. O tipo SQL
obviamente significa que foi rodado um script SQL, já o tipo baseline
é um tipo especial de migração que indica o começo do versionamento da base de dados, ou seja, não foi feita uma alteração na base. Analogamente ao que ocorre no git, seria o commit inicial.
Vale dizer que é possível utilizar Java Migrations, ou seja, migrações com código Java. Elas não serão cobertas aqui, mas podem ser bastante interessantes para casos mais complextos onde a utilização somente de SQL se torne muito difícil, ou mesmo impossível, como recalcular valores com uma nova fórmula, ou alterações avançadas de formato.
Voltando a tabela do exemplo, temos as colunas script
e checksum
que apresentam respectivamente o nome e o checksum do arquivo da migração executada. Por meio do checksum, o Flyway pode validar se houve alguma alteração em arquivos de migração que já foram executados na base.
Por fim, as colunas installed_by
, installed_on
, execution_time
e success
indicam respectivamente o usuário que executou a migração, a data em que ela foi executada, o tempo de execução e se houve sucesso ou não. Esse último campo sempre será marcado como true, caso sua base permita DDL transactions, pois nesse caso o próprio Flyway realiza automaticamente o rollback da migração. Caso sua base não permita, então a migração é marcada como sem sucesso (false), necessitando nesse caso de intervenção manual.
Perceba que essa tabela criada pelo Flyway, por padrão com o nome flyway_schema_history
, não é somente um log das migrações, mas também permite fazer a validação dos arquivos de migração, controlar a versão da base e identificar o usuário responsável por cada migração.
Conclusão
Torço para que tenha ficado claro as vantagens de utilizar Flyway, e como ele gerencia a versão da sua base de dados. No próximo post, vamos ver como utilizá-lo (usando Docker) para efetivamente aplicar as migrações na sua base de dados. Se ficaram dúvidas, comente aqui. Abraços e até a próxima.