urls template httpresponseredirect example django django-migrations

template - django revierte la última migración



httpresponseredirect django parameters (7)

Aquí está mi solución, ya que la solución anterior realmente no cubre el caso de uso, cuando usa RunPython .

Puede acceder a la tabla a través del ORM con

from django.db.migrations.recorder import MigrationRecorder >>> MigrationRecorder.Migration.objects.all() >>> MigrationRecorder.Migration.objects.latest(''id'') Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model> >>> MigrationRecorder.Migration.objects.latest(''id'').delete() Out[4]: (1, {u''migrations.Migration'': 1})

Por lo tanto, puede consultar las tablas y eliminar las entradas que sean relevantes para usted. De esta manera puede modificar en detalle. Con RynPython migraciones de RynPython , también debe cuidar los datos que se agregaron / cambiaron / eliminaron. El ejemplo anterior solo muestra cómo accede a la tabla a través de Djang ORM.

He realizado una migración que agregó una nueva tabla y quiero revertirla y eliminar la migración, sin crear una nueva migración.

¿Cómo lo hago? ¿Existe un comando para revertir la última migración y luego simplemente puedo eliminar el archivo de migración?


Esta respuesta es para casos similares si la respuesta principal de Alasdair no ayuda . (Por ejemplo, si la migración no deseada se crea pronto nuevamente con cada nueva migración o si se trata de una migración más grande que no se puede revertir o la tabla se ha eliminado manualmente).

... eliminar la migración, sin crear una nueva migración?

TL; DR : puede eliminar algunas migraciones revertidas (confusas) y hacer una nueva después de corregir los modelos . También puede usar otros métodos para configurarlo para que no cree una tabla mediante el comando migrate. La última migración debe crearse para que coincida con los modelos actuales .

Casos por los cuales alguien no quiere crear una tabla para un Modelo que debe existir:

A) No debería existir tal tabla en ninguna base de datos en ninguna máquina y sin condiciones

  • Cuándo: es un modelo base creado solo para la herencia del modelo de otro modelo.
  • Solución: Establecer class Meta: abstract = True

B) La tabla se crea raramente, por otra cosa o manualmente de una manera especial.

  • Solución: use la class Meta: managed = False
    La migración se crea, pero nunca se usa, solo en pruebas. El archivo de migración es importante, de lo contrario las pruebas de la base de datos no pueden ejecutarse, comenzando desde el estado inicial reproducible.

C) La tabla se usa solo en algunas máquinas (por ejemplo, en desarrollo).

  • Solución: mueva el modelo a una nueva aplicación que se agregue a INSTALLED_APPS solo en condiciones especiales o use una class Meta: managed = some_switch condicional class Meta: managed = some_switch .

D) El proyecto utiliza múltiples bases de datos en la settings.DATABASES

  • Solución: escriba un enrutador de base de datos con el método allow_migrate para diferenciar las bases de datos donde se debe crear la tabla y dónde no.

La migración se crea en todos los casos A), B), C), D) con Django 1.9+ (y solo en los casos B, C, D con Django 1.8), pero se aplica a la base de datos solo en los casos apropiados o tal vez nunca si requerido así. Las migraciones han sido necesarias para ejecutar pruebas desde Django 1.8. Las migraciones registran el estado actual relevante completo, incluso para modelos con Managed = False en Django 1.9+ para que sea posible crear una ForeignKey entre modelos administrados / no administrados o para que el modelo sea administrado = True más adelante. (Esta pregunta se ha escrito en el momento de Django 1.8. Todo aquí debería ser válido para versiones entre la 1.8 y la 2.2 actual).

Si la última migración es (no) es fácilmente reversible, entonces es posible realizar con cautela (después de la copia de seguridad de la base de datos) una reversión falsa ./manage.py migrate --fake my_app 0010_previous_migration , elimine la tabla manualmente.

Si es necesario, cree una migración fija desde el modelo fijo y aplíquela sin cambiar la estructura de la base de datos ./manage.py migrate --fake my_app 0011_fixed_migration .


Hice esto en 1.9.1 (para eliminar la última o la última migración creada):

  1. rm <appname>/migrations/<migration #>*

    ejemplo: rm myapp/migrations/0011*

  2. inició sesión en la base de datos y ejecutó este SQL (postgres en este ejemplo)

    delete from django_migrations where name like ''0011%'';

Luego pude crear nuevas migraciones que comenzaron con el número de migración que acababa de eliminar (en este caso, 11).


La otra cosa que puede hacer es eliminar la tabla creada manualmente.

Junto con eso, tendrá que eliminar ese archivo de migración en particular. Además, deberá eliminar esa entrada en particular en la tabla django-migrations (probablemente la última en su caso) que se correlaciona con esa migración en particular.


La respuesta de Alasdair cubre los conceptos básicos.

  • Identifique las migraciones que desea mediante ./manage.py showmigrations
  • migrate usando el nombre de la aplicación y el nombre de la migración

Pero debe señalarse que no todas las migraciones pueden revertirse. Esto sucede si Django no tiene una regla para hacer la inversión. Para la mayoría de los cambios que realizó migraciones automáticamente mediante ./manage.py makemigrations , la reversión será posible. Sin embargo, las secuencias de comandos personalizadas deberán tener una escritura tanto directa como inversa, como se describe en el ejemplo aquí:

https://docs.djangoproject.com/en/1.9/ref/migration-operations/

Cómo hacer una inversión sin operación

Si tuvo una operación RunPython , entonces tal vez solo quiera retroceder la migración sin escribir un script de inversión lógicamente riguroso. El siguiente truco rápido para el ejemplo de los documentos (enlace anterior) permite esto, dejando la base de datos en el mismo estado que tenía después de que se aplicara la migración, incluso después de revertirla.

# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import migrations, models def forwards_func(apps, schema_editor): # We get the model from the versioned app registry; # if we directly import it, it''ll be the wrong version Country = apps.get_model("myapp", "Country") db_alias = schema_editor.connection.alias Country.objects.using(db_alias).bulk_create([ Country(name="USA", code="us"), Country(name="France", code="fr"), ]) class Migration(migrations.Migration): dependencies = [] operations = [ migrations.RunPython(forwards_func, lambda apps, schema_editor: None), ]

Esto funciona para Django 1.8, 1.9

Actualización: una mejor manera de escribir esto sería reemplazar las lambda apps, schema_editor: None con migrations.RunPython.noop en el fragmento anterior. Ambos son funcionalmente la misma cosa. (crédito a los comentarios)


Puede revertir migrando a la migración anterior.

Por ejemplo, si sus dos últimas migraciones son:

  • 0010_previous_migration
  • 0011_migration_to_revert

Entonces harías:

./manage.py migrate my_app 0010_previous_migration

Luego puede eliminar la migración 0011_migration_to_revert .

Si está utilizando Django 1.8+, puede mostrar los nombres de todas las migraciones con

./manage.py showmigrations my_app

Para revertir todas las migraciones de una aplicación, puede ejecutar:

./manage.py migrate my_app zero


Si tiene problemas al revertir la migración, y de alguna manera lo ha desordenado, puede realizar migraciones fake .

./manage.py migrate <name> --ignore-ghost-migrations --merge --fake

Para la versión django <1.7 esto creará una entrada en la tabla south_migrationhistory , debe eliminar esa entrada.

Ahora podrá revertir la migración fácilmente.

PD: Estuve atrapado durante mucho tiempo y realizar una migración falsa y luego volver atrás me ayudó.