Gerenciando migrações em clojure com Migratus

Migratus e PostgreSQL

migratus!

Esse seria um passo extra da primeira parte da API de invoices que comecei neste outro post.

De maneira geral podemos dizer que o Migratus é uma implementação simples para gerenciar migrações como scripts SQL ou código Clojure geral.

Para usa-lo basta adicionar a dependência no projeto.

[migratus "1.3.6"]

Como estou usando o postgres, é necessário adicionar a lib que faz a conexão com o banco de dados.

[org.postgresql/postgresql "42.1.4"]

Pronto! Isso seria o bastante para ter o Migratus passando as configurações de conexão no REPL, porém, em alguns casos, eu prefiro usar a API do Migratus como uma command line, então, eu também uso o plugin do migratus para o lein.

Na chave :plugins basta declarar o uso do plugin.

[migratus-lein "0.7.3"]

E uma nova key chamada :migratus no arquivo project.clj

:migratus {:store :database
             :migration-dir "migrations"
             :db {:classname "org.postgresql.Driver"
                  :subprotocol "postgresql"
                  :subname "//localhost:5432/invoice_api_dev"
                  :user "postgres"
                  :password "postgres"}}

No final, o arquivo project.clj se parecerá com:

(defproject invoice_api "0.1.0-SNAPSHOT"
  :description "Invoice Api aristotelesbr"
  :url "https://aristotelescoutinho.com.br/invoices"
  :min-lein-version "2.0.0"
  + :migratus {:store :database
  +           :migration-dir "migrations"
  +           :db {:classname "org.postgresql.Driver"
  +                :subprotocol "postgresql"
  +                :subname "//localhost:5432/invoice_api_dev"
  +                :user "postgres"
  +                :password "postgres"}}
  + :dependencies [[org.clojure/clojure "1.10.0"]
                 ;; ...
                 ;; ...
  +               [migratus "1.3.5"]
  +               [org.postgresql/postgresql "42.1.4"]]
  + :plugins [[migratus-lein "0.7.3"]]
  :ring {:handler invoice-api.handler/app}
  :profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring/ring-mock "0.3.2"]]}})

Agora, se tudo tiver ocorrido bem, será possível gerenciar as migrações de forma pragmática.

Você pode verificar os camandos disponívels aqui

Criando a tabela

Gerando os arquivos de migração

$ lein migratus create add-invoices-table

creating migration files for add-invoices-table
nil

Após executar o comando acima, o script irá criar um pasta(se ela ainda não existir) chamada resources/migrations, com os arquivos de migração.

Estrutura de diretórios

Agora basta colocar o SQL correspondente a criação da tabela desejada:

-- xpto.up.sql

CREATE TABLE IF NOT EXISTS invoices( 
  code VARCHAR(256),
  id SERIAL PRIMARY KEY,
  title VARCHAR(256) NOT NULL,
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP 
);

e o inverso seria:

-- xpto.down.sql

DROP TABLE IF EXISTS invoices;

⚠️ Até onde vi na documentação do Migratus não tem como criar o banco de dados usando a CLI, então, lembre-se de criar o banco antes de executar o comando

Agora basta executar no terminal:

$ lein migratus migrate

Se as configurações de conexão estiverem corretas, as "changes" serão persistidas no banco.

postbird dashboard

O que vem depois?

Seria interessante ter um namespace para gerenciar as migrations a nível de aplicação. Aqui tem uma ideia de como fazer isso. 😉

Referências

👉 migratus 👉 migratus-lein 👉 Código/Repositório

Comentários