Fiz uma migração que adicionou uma nova tabela e deseja revertê-la e excluir a migração, sem criar uma nova migração.
Como eu faço isso? Existe um comando para reverter a última migração e, em seguida, posso simplesmente excluir o arquivo de migração?
django
django-migrations
Ronen Ness
fonte
fonte
migrate
comando permite que você./manage.py migrate my_app zero
aplique todas as migrações para o aplicativo.'0010_previous_migration'
, não sei por que você veria esse comportamento.A resposta da Alasdair cobre o básico
./manage.py showmigrations
migrate
usando o nome do aplicativo e o nome da migraçãoMas deve-se ressaltar que nem todas as migrações podem ser revertidas. Isso acontece se o Django não tem uma regra para fazer a reversão. Para a maioria das alterações pelas quais você fez as migrações automaticamente
./manage.py makemigrations
, a reversão será possível. No entanto, os scripts personalizados precisarão de gravação direta e reversa, conforme descrito no exemplo aqui:https://docs.djangoproject.com/en/1.9/ref/migration-operations/
Como fazer uma reversão sem operação
Se você teve uma
RunPython
operação, talvez queira apenas voltar a migração sem escrever um script de reversão logicamente rigoroso. O seguinte hack rápido para o exemplo a partir dos documentos (link acima) permite isso, deixando o banco de dados no mesmo estado em que estava após a aplicação da migração, mesmo depois de revertê-lo.Isso funciona para o Django 1.8, 1.9
Update: A melhor maneira de escrever este seria substituir
lambda apps, schema_editor: None
commigrations.RunPython.noop
no trecho acima. Ambos são funcionalmente a mesma coisa. (crédito aos comentários)fonte
RunPython.noop
vez de um lambda inline ou equivalente: docs.djangoproject.com/en/1.8/ref/migration-operations/…migrations.RunPython(forwards_func, migrations.RunPython.noop)
. Precisa verificar isso funcionalmente. Isso deve ser adicionado como resposta ou edição a este em algum momento.Aqui está minha solução, já que a solução acima não cobre realmente o caso de uso quando você o usa
RunPython
.Você pode acessar a tabela via ORM com
Assim, você pode consultar as tabelas e excluir as entradas relevantes para você. Dessa forma, você pode modificar em detalhes. Com as
RynPython
migrações, você também precisa cuidar dos dados que foram adicionados / alterados / removidos. O exemplo acima mostra apenas como você acessa a tabela via Djang ORM.fonte
django.db.utils.ProgrammingError: relation "<relation name>" already exists
assim, eu fiz ummigrate --fake
que está errado, então eu tentei voltar, então eupsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
OBRIGADOA outra coisa que você pode fazer é excluir a tabela criada manualmente.
Junto com isso, você terá que excluir esse arquivo de migração específico. Além disso, você terá que excluir essa entrada específica na tabela django-migrations (provavelmente a última no seu caso) que se correlaciona com essa migração específica.
fonte
Não exclua o arquivo de migração até depois da reversão. Cometi esse erro e, sem o arquivo de migração, o banco de dados não sabia o que remover.
Exclua o arquivo de migração. Quando a migração desejada estiver em seus modelos ...
fonte
Fiz isso no 1.9.1 (para excluir a última ou mais recente migração criada):
rm <appname>/migrations/<migration #>*
exemplo:
rm myapp/migrations/0011*
logado no banco de dados e executou este SQL (postgres neste exemplo)
delete from django_migrations where name like '0011%';
Pude criar novas migrações que começaram com o número de migração que eu havia acabado de excluir (neste caso, 11).
fonte
Esta resposta é para casos semelhantes, se a resposta principal da Alasdair não ajudar . (Por exemplo, se a migração indesejada for criada em breve novamente a cada nova migração ou se houver uma migração maior que não possa ser revertida ou se a tabela tiver sido removida manualmente.)
TL; DR : você pode excluir algumas das últimas migrações revertidas (confusas) e fazer uma nova após corrigir os modelos . Você também pode usar outros métodos para configurá-lo para não criar uma tabela pelo comando migrate. A última migração deve ser criada para corresponder aos modelos atuais .
Casos em que alguém não deseja criar uma tabela para um Modelo que deve existir:
A) Nenhuma tabela deve existir em nenhum banco de dados em nenhuma máquina e sem condições
class Meta: abstract = True
B) A tabela é criada raramente, por outra coisa ou manualmente de uma maneira especial.
class Meta: managed = False
A migração é criada, mas nunca usada, apenas em testes. O arquivo de migração é importante, caso contrário, os testes do banco de dados não podem ser executados, iniciando a partir do estado inicial reproduzível.
C) A tabela é usada apenas em algumas máquinas (por exemplo, em desenvolvimento).
class Meta: managed = some_switch
.D) O projeto utiliza vários bancos de dados em
settings.DATABASES
allow_migrate
para diferenciar os bancos de dados onde a tabela deve ser criada e onde não.A migração é criada em todos os casos A), B), C), D) com Django 1.9+ (e somente nos casos B, C, D com Django 1.8), mas aplicada ao banco de dados apenas nos casos apropriados ou talvez nunca se necessário. Migrações são necessárias para a execução de testes desde o Django 1.8. O estado atual relevante completo é registrado pelas migrações, mesmo para os modelos com managed = False no Django 1.9+, para ser possível criar uma ForeignKey entre modelos gerenciados / não gerenciados ou para tornar o modelo gerenciado = True mais tarde. (Esta pergunta foi escrita na época do Django 1.8. Tudo aqui deve ser válido para versões entre 1.8 e 2.2.)
Se a última migração não for facilmente revertível, é possível com cautela (após o backup do banco de dados) fazer uma reversão falsa
./manage.py migrate --fake my_app 0010_previous_migration
, exclua a tabela manualmente.Se necessário, crie uma migração fixa a partir do modelo fixo e aplique-a sem alterar a estrutura do banco de dados
./manage.py migrate --fake my_app 0011_fixed_migration
.fonte
Se você estiver enfrentando problemas ao reverter a migração e, de alguma forma, tiver estragado tudo, poderá realizar
fake
migrações.Para a versão do django <1.7, isso criará uma entrada na
south_migrationhistory
tabela, você precisará excluir essa entrada.Agora você poderá reverter a migração facilmente.
PS: Fiquei preso por muito tempo, realizando uma migração falsa e, em seguida, reverter novamente me ajudou.
fonte