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? ¿Hay un comando para revertir la última migración y luego simplemente puedo eliminar el archivo de migración?
django
django-migrations
Ronen Ness
fuente
fuente
migrate
comando le permite usar./manage.py migrate my_app zero
para no aplicar todas las migraciones de la aplicación.'0010_previous_migration'
, no sé por qué vería ese comportamiento.La respuesta de Alasdair cubre los conceptos básicos.
./manage.py showmigrations
migrate
usando el nombre de la aplicación y el nombre de la migraciónPero 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 por los que realizó migraciones automáticamente
./manage.py makemigrations
, será posible la reversión. 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
RunPython
operación, tal vez solo quiera retroceder la migración sin escribir un guión de inversión lógicamente riguroso. El siguiente truco rápido para el ejemplo de los documentos (enlace anterior) lo permite, 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.Esto funciona para Django 1.8, 1.9
Actualización: Una mejor manera de escribir esta sería la de sustituir
lambda apps, schema_editor: None
conmigrations.RunPython.noop
el fragmento anterior. Ambos son funcionalmente la misma cosa. (crédito a los comentarios)fuente
RunPython.noop
lugar de un lambda en línea o equivalente: docs.djangoproject.com/en/1.8/ref/migration-operations/…migrations.RunPython(forwards_func, migrations.RunPython.noop)
. Necesito verificar eso funcionalmente. Eso debería agregarse como respuesta o edición en algún momento.Aquí está mi solución, ya que la solución anterior realmente no cubre el caso de uso, cuando lo usa
RunPython
.Puede acceder a la tabla a través del ORM con
Por lo tanto, puede consultar las tablas y eliminar las entradas que sean relevantes para usted. De esta manera puede modificar en detalle. Con las
RynPython
migraciones 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.fuente
django.db.utils.ProgrammingError: relation "<relation name>" already exists
que hice, lomigrate --fake
cual es incorrecto, así que traté de regresar, luego obtuvepsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
GRACIASLa 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, tendrá que 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.
fuente
No elimine el archivo de migración hasta después de la reversión. Cometí este error y sin el archivo de migración, la base de datos no sabía qué cosas eliminar.
Eliminar el archivo de migración. Una vez que la migración deseada esté en sus modelos ...
fuente
Hice esto en 1.9.1 (para eliminar la última o la última migración creada):
rm <appname>/migrations/<migration #>*
ejemplo:
rm myapp/migrations/0011*
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).
fuente
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).
TL; DR : puede eliminar algunas de las últimas 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
class Meta: abstract = True
B) La tabla se crea raramente, por otra cosa o manualmente de una manera especial.
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).
class Meta: managed = some_switch
.D) El proyecto utiliza múltiples bases de datos en
settings.DATABASES
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 no es (son) fácilmente reversibles, 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
, eliminar 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
.fuente
Si tiene problemas al revertir la migración, y de alguna manera lo ha desordenado, puede realizar
fake
migraciones.Para django versión <1.7 esto creará una entrada en la
south_migrationhistory
tabla, 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ó.
fuente