HOWTO · Django

Reverter a última migração de banco de dados no Django

Este artigo fornece uma discussão sobre como você pode reverter para a última migração de banco de dados no Django.

Nesta página

Para desfazer a migração mais recente do Django que foi aplicada, execute python manage.py migrate <app_label> <migration_name> e escolha a migração que deve continuar aplicada, geralmente a imediatamente anterior à que você quer reverter. O Django reverte as migrações posteriores a esse destino no aplicativo indicado. Primeiro, use showmigrations para verificar o estado atual do aplicativo. Faça backup dos dados importantes antes da reversão: reverter operações de esquema pode descartar dados, e algumas operações não podem ser revertidas.

Reverter até uma migração específica

Use python manage.py showmigrations <app_label> para listar as migrações de um aplicativo. As migrações aplicadas têm a marca [X]; as não aplicadas têm [ ]. O rótulo do aplicativo é o nome da aplicação Django usado nos comandos de migração, e o nome da migração é a parte do nome do arquivo sem .py.

Por exemplo, suponha que blog tenha 0001_initial, 0002_add_author e 0003_remove_legacy_field, e que as três estejam aplicadas. Para desfazer somente 0003_remove_legacy_field, use 0002_add_author como destino: python manage.py migrate blog 0002_add_author. O destino indica o estado final das migrações que você quer manter, não a migração que deseja desfazer. O Django reverte 0003 e todas as migrações posteriores aplicadas em blog. Um prefixo numérico como 0002 pode identificar o destino, mas usar o nome completo deixa a escolha mais clara.

Execute o comando no ambiente do projeto em que manage.py consiga carregar as configurações e a conexão corretas com o banco de dados. Antes de prosseguir, confirme o aplicativo e o banco de dados de destino, especialmente se houver vários ambientes configurados.

Execute este trecho de Python para imprimir um comando para um aplicativo e um destino:

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

app_label = "blog"
target = "0002_add_author"
print(f"python manage.py migrate {app_label} {target}")
python manage.py migrate blog 0002_add_author

O trecho apenas formata o comando; execute o comando impresso no seu projeto Django para alterar o estado do banco de dados.

Reverter todas as migrações de um aplicativo

Para reverter todas as migrações aplicadas de um aplicativo, use python manage.py migrate <app_label> zero, por exemplo python manage.py migrate blog zero. Nesse caso, zero é o estado de destino em que nenhuma migração daquele aplicativo está aplicada. O Django reverte o histórico de migrações do aplicativo na ordem inversa. Isso não significa “desfazer a migração mais recente” e pode remover tabelas ou colunas, além dos dados nelas. Revise a lista de migrações do aplicativo e faça backup do banco de dados antes de usar esse destino.

Para reverter várias migrações, mas não todas, especifique uma migração anterior como destino. O Django retrocede a partir do estado atualmente aplicado até chegar a esse destino. Migrações de outros aplicativos não são selecionadas só por serem posteriores no histórico geral do projeto, embora as dependências possam afetar o plano. Antes de confirmar uma alteração em produção, leia as operações planejadas pelo Django.

Entenda a reversibilidade e a perda de dados

O Django consegue reverter uma operação quando a migração define uma operação reversa ou quando o Django consegue inferi-la. Algumas operações, como excluir dados com uma operação personalizada em Python sem função reversa, não podem ser reconstruídas. Tentar reverter uma migração assim gera IrreversibleError. Inspecione as operações da migração e a mensagem de erro completa para identificar a etapa sem caminho de reversão; não suponha que restaurar um arquivo de migração antigo torne reversíveis os efeitos que ela teve no banco de dados.

Mesmo uma alteração reversível no esquema pode causar perda de dados. Por exemplo, reverter a remoção de um campo não recupera os valores descartados quando ele foi removido. Antes de reverter, faça um backup do banco de dados, verifique se é necessário pausar as gravações da aplicação e avalie se uma correção progressiva seria mais segura. Em produção, ensaie o procedimento usando um backup recente e confirme o plano de recuperação antes de alterar o banco de dados ativo.

O Git gerencia os arquivos de código-fonte das migrações, enquanto migrate altera o estado do banco de dados. Fazer checkout ou reverter um commit no Git não reverte o banco de dados por si só. Restaurar arquivos de migração separadamente também pode deixar o código inconsistente com o histórico de migrações registrado. Portanto, use os comandos de migração do Django para a operação no banco de dados e coordene qualquer recuperação de código à parte.

Verifique o estado do banco de dados

Quando o comando terminar, execute novamente python manage.py showmigrations <app_label>. Confirme que o destino pretendido e as migrações anteriores aparecem com [X], e que as migrações revertidas aparecem com [ ]. Isso mostra o estado das migrações registrado pelo Django; não verifica todas as expectativas sobre os dados da aplicação nem comprova que o esquema e os dados estejam íntegros. Verifique o comportamento da aplicação afetada e, quando necessário, inspecione o banco de dados ou execute verificações específicas do projeto.

Se as marcas não corresponderem ao destino pretendido, pare antes de fazer outra reversão. Confirme que está conectado ao banco de dados correto, revise a saída do comando e as dependências entre migrações e, então, decida a próxima operação com base no estado realmente registrado.