A Dor da Evolução do Banco de Dados em Projetos Ágeis
Em projetos de desenvolvimento de software, especialmente aqueles que adotam metodologias ágeis, a arquitetura do banco de dados está em constante evolução. Refatorar o esquema do banco de dados no meio do projeto pode se tornar uma grande dor de cabeça, impactando diretamente as entregas e a estabilidade da aplicação. Mudanças em tabelas, colunas ou relacionamentos precisam ser coordenadas cuidadosamente entre os desenvolvedores e aplicadas de forma consistente em diferentes ambientes (desenvolvimento, homologação, produção).
É nesse cenário que o versionamento de banco de dados se torna não apenas uma boa prática, mas uma necessidade crítica. Assim como versionamos o código-fonte da nossa aplicação para rastrear alterações, reverter para versões anteriores e colaborar de forma eficiente, precisamos de uma abordagem similar para o esquema do nosso banco de dados.
Alembic: A Solução para Evolução Controlada do Banco de Dados
O Alembic[1] é uma ferramenta de migração de banco de dados leve, desenvolvida para o SQLAlchemy[2], o popular toolkit SQL e Object-Relational Mapper (ORM). Ele permite que você evolua o esquema do seu banco de dados de forma incremental e controlada, garantindo que as alterações sejam aplicadas de maneira previsível e reversível.
O Alembic trabalha diretamente com a camada de Data Definition Language (DDL), ou seja, as operações que definem a estrutura do banco de dados (criar tabelas, adicionar colunas, etc.). Ele gera scripts de migração que podem ser executados para upgrade (aplicar mudanças) ou downgrade (reverter mudanças), proporcionando um controle total sobre o estado do seu esquema.
Configurando o Alembic em Seu Projeto
Para começar a usar o Alembic em seu projeto Python, siga os passos abaixo:
1. Instalação
Primeiro, adicione o Alembic como uma dependência do seu projeto. Se você estiver usando poetry para gerenciamento de dependências, execute:
poetry add alembic
Ou, se preferir pip:
pip install alembic
2. Inicialização do Ambiente de Migração
Após a instalação, você precisa inicializar o ambiente de migração do Alembic. Isso criará uma estrutura de diretórios e arquivos de configuração essenciais. O comando alembic init cria uma pasta onde suas migrações serão armazenadas e um arquivo de configuração principal.
alembic init migrations
Este comando criará um diretório migrations (ou o nome que você especificar) e um arquivo alembic.ini na raiz do seu projeto. O diretório migrations conterá:
-
env.py: O ambiente de execução do Alembic, onde você configura como o Alembic interage com seu banco de dados e modelos SQLAlchemy. -
script.py.mako: Um template para novos scripts de migração. -
versions/: Um diretório onde os arquivos de migração gerados serão armazenados.
3. Configuração do alembic.ini
O arquivo alembic.ini é o coração da configuração do Alembic. Ele contém configurações gerais, como a URL de conexão com o banco de dados. Por padrão, ele é configurado para um único banco de dados.
Localize a linha sqlalchemy.url e atualize-a com a string de conexão do seu banco de dados. Por exemplo:
# alembic.ini
[alembic]
...
sqlalchemy.url = postgresql://user:password@host:port/database_name
# ou para SQLite
# sqlalchemy.url = sqlite:///./sql_app.db
...
Importante: Para ambientes de produção, é uma boa prática usar variáveis de ambiente para a string de conexão do banco de dados, em vez de codificá-la diretamente no alembic.ini. Você pode configurar isso no arquivo env.py para ler a URL de uma variável de ambiente.
Criando Sua Primeira Migração (Manual)
Com o Alembic configurado, você pode criar sua primeira migração. Uma migração é um script Python que descreve as alterações no esquema do banco de dados. Cada migração possui duas funções principais:
-
upgrade(): Contém o código para aplicar as alterações no banco de dados. -
downgrade(): Contém o código para reverter as alterações feitas porupgrade().
Para criar um novo arquivo de migração, use o comando alembic revision:
alembic revision -m "create_initial_tables"
Este comando gerará um novo arquivo Python no diretório versions/ (ex: xxxxxxxxxxxx_create_initial_tables.py). O nome do arquivo incluirá um identificador único e a mensagem que você forneceu. O conteúdo será similar a este:
# versions/xxxxxxxxxxxx_create_initial_tables.py
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'xxxxxxxxxxxx'
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
Neste ponto, você preencheria as funções upgrade() e downgrade() com as operações DDL necessárias, usando as construções do SQLAlchemy Core. Por exemplo, para criar uma tabela users:
# versions/xxxxxxxxxxxx_create_initial_tables.py
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'xxxxxxxxxxxx'
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table(
'users',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('email', sa.String(100), unique=True, nullable=False)
)
def downgrade() -> None:
op.drop_table('users')
Para aplicar esta migração ao seu banco de dados, execute:
alembic upgrade head
O comando head instrui o Alembic a aplicar todas as migrações pendentes até a mais recente. Se você precisar reverter a última migração, use:
alembic downgrade -1
Próximos Passos: Migrações Automáticas e Bancos Existentes
Na Parte 2 deste artigo, exploraremos como o Alembic pode gerar migrações automaticamente com base nas mudanças detectadas em seus modelos SQLAlchemy, um recurso que agiliza significativamente o processo de desenvolvimento. Também abordaremos o desafio de integrar o Alembic a um banco de dados que já possui tabelas existentes, um cenário comum em projetos legados ou em andamento.
Referências
[1] Alembic Documentation: https://alembic.sqlalchemy.org/en/latest/
[2] SQLAlchemy Documentation: https://www.sqlalchemy.org/
Top comments (0)