Marcelo Lino
Posted on January 4, 2023
Uma das coisas mais ferramentas mais poderosas do framework Django é o seu ORM e o gerenciamento de migrações. Porém quando enfrentamos um ambiente produtivo, por diversas vezes temos que executar migrações que adicionam, removem ou alteram colunas, o que causa uma indisponibilidade no sistema, até que o novo código que comporte essa nova estrutura do modelo esteja disponível para atender as requisições.
O fluxo de implantação de um novo código de aplicação Django geralmente consiste em:
O problema acontece pois entre a Execução da Migração e a Execução do Novo Código o Código Atual ainda estará em execução até que o novo possa assumir, fazendo com que o Django dispare um IntegrityError
deixando todas as suas gravações de dados indisponíveis nesse período de tempo.
Pra solucionar esse problema temos alguns procedimentos que podemos seguir.
Adicionando Campos ou Tabelas
Adicionar um campo NULL
ou nova tabela
- Crie o modelo ou a coluna no seu código;
- Gere as respectivas migrações com
python manage.py makemigrations
; - Faça duas Pull Requests, uma contendo a alteração do modelo e outra com a respectiva migração;
- Faça o Merge e a implantação da Pull Request com a migração;
- Execute a migração no seu banco de dados de produção. Adição de campos não deve causar problemas se o modelo em produção não esperar que esses campos estejam lá;
- Faça o Merge da Pull Request com a mudança no modelo;
- Implante o código com a mudança do modelo. A partir de agora o código vai começar a ler e escrever na nova coluna.
Adicionando um campo NOT NULL
Para iniciar a adição de um campo NÂO NULO, primeiro siga os passos acima adicionando ele como NULO inicialmente
- Altere a coluna no modelo para
null=False
. Certifique-se que no seu código você não está inserindo ou atualizando esse campo com valores nulos; - Gere as respectivas migrações com
python manage.py makemigrations
; - Faça duas Pull Requests, uma contendo a alteração do modelo e outra com a respectiva migração;
- Faça o Merge da Pull Request com a mudança no modelo;
- Implante o código com a mudança do modelo. A partir de agora o código vai começar a gravar na nova coluna.
- Faça o Merge e a implantação da Pull Request com a migração;
- Execute a migração no seu banco de dados de produção.
Adicionando NOT NULL
em tabelas com muitos dados
As migrações do Django insistem que se exista um valor default para colunas com a constraint NOT NULL
. Esse valor será usado para popular as colunas vazias durante a migração. Esse processo de atualização efetuará um LOCK
na tabela para escrita até que a atualização esteja concluída. Para tabelas pequenas com menos de 100.000 linhas, provavelmente não haverá problemas, porém para colunas com mais dados isso pode causar uma indisponibilidade do sistema até que a tabela esteja novamente disponível.
Afim de evitar esse comportamento, podemos executar Migrações Não Atômicas, simplesmente adicionando o atributo atomic = False
a sua migração, como no exemplo a seguir.
from django.db import migrations
class Migration(migrations.Migration):
atomic = False
Removendo Campos ou Tabelas
Removendo um campo NULL
ou uma Tabela
Basicamente é o mesmo procedimento de adição, porém com os passo em uma ordem um pouco diferente.
- Remova todas as utilizações do modelo ou coluna a serem removidas da sua aplicação;
- Faça a implantação de uma versão que ainda tenha a definição da coluna ou modelo a ser removida, porém que não tenha mais a sua utilização;
- Faça a remoção da coluna ou modelo do seu código;
- Gere a migração para a remoção com
python manage.py makemigrations
; - Faça o Merge da mudança do modelo;
- Implante o código da mudança do modelo. Certifique-se que não está ocorrendo nenhum erro por ainda existir alguma referência ao código que não mais existe;
- Faça o Merge da migração;
- Implante o código da migração;
- Execute a migração no seu banco de dados.
Removendo um campo NOT NULL
Para remover um campo não nulo, primeiramente você tem que transformá-lo em um campo nulo, então seguir os passos a cima para remover um campo não nulo. Os passos para transformar o campo não nulo em nulo são:
- Alterar o seu campo para
null=True
; - Criar as migrações para esse mudança;
- Criar duas Pull Requests separadas, uma para a mudança no modelo e outra para migração;
- Fazer o Merge e implantar o Pull Request com a migração;
- Execute a migração no banco de dados;
- Faça o Merge e a implantação da mudança do modelo;
- Execute os passos para remover um campo nulo
Posted on January 4, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.