¿Cuál es el enfoque recomendado para restablecer el historial de migración con Django South?


153

He acumulado bastantes migraciones usando South (0.7) y Django (1.1.2) que están comenzando a consumir bastante tiempo en mis pruebas unitarias. Me gustaría restablecer la línea de base y comenzar un nuevo conjunto de migraciones. Revisé la documentación de South , hice la búsqueda habitual de Google / Stackoverflow (por ejemplo, "django south (restablecer o eliminar o eliminar) historial de migración") y no he encontrado nada obvio.

Un enfoque que he contemplado implicaría "comenzar de nuevo" al "eliminar" South o "borrar" el historial manualmente (por ejemplo, borrar la tabla db, eliminar archivos de migración del director de migraciones) y simplemente volver a ejecutar,

./manage.py schemamigration southtut --inicial

Entonces, si alguien ha hecho esto antes y tiene algunos consejos / sugerencias, sería muy apreciado.


a veces necesita agregar manualmente __init__.pyaappname/migrations
laike9m

2
¿Cómo restablece las migraciones en 1.7 (con la migración integrada)?
Timo

1
@Timo: docs.djangoproject.com/en/dev/topics/migrations/… podría ser un enfoque. También puede simplemente eliminar sus migraciones / directorios y volver a emitir, ./manage.py makemigrationspero sucederán cosas malas si no comienza desde una nueva base de datos ...
Jocelyn delalande

Creo que squashmigrationses la respuesta correcta
Julio Marins

Respuestas:


121

EDITAR: pongo un comentario a continuación en la parte superior de esto, ya que es importante leerlo antes de la> respuesta aceptada que sigue a @andybak

@Dominique: Su consejo con respecto al reinicio de manage.py south es peligroso y puede destruir la base de datos si hay aplicaciones de terceros que usan south en el proyecto, como señala @thnee a continuación. Dado que su respuesta tiene tantos votos positivos, realmente lo agradecería si pudiera editarlo y agregar al menos una advertencia al respecto, o (aún mejor) cambiarlo para reflejar el enfoque @hobs (que es igual de conveniente, pero no afectar otras aplicaciones) - ¡gracias! - chrisv 26 de marzo de 13 a 9:09

La respuesta aceptada sigue a continuación:

Primero, una respuesta del autor del Sur :

Siempre que tenga cuidado de hacerlo en todas las implementaciones simultáneamente, no debería haber ningún problema con esto. Personalmente, haría:

    rm -r appname/migrations/ 
    ./manage.py reset south 
    ./manage.py convert_to_south appname 

(Tenga en cuenta que la parte " reset south" borra los registros de migración para TODAS las aplicaciones, así que asegúrese de ejecutar las otras dos líneas para todas las aplicaciones o eliminarlas selectivamente).

La convert_to_southllamada al final realiza una nueva migración y la aplica falsamente (ya que su base de datos ya tiene las tablas correspondientes). No es necesario descartar todas las tablas de aplicaciones durante el proceso.

Esto es lo que estoy haciendo en mi servidor de producción dev + cuando necesito deshacerme de todas estas migraciones de desarrollo innecesarias:

  1. Asegúrese de tener el mismo esquema de base de datos en ambos lados
  2. eliminar todas las carpetas de migraciones en ambos lados
  3. ejecute ./manage.py restablecer al sur (como dice la publicación) en ambos lados = borra la tabla sur *
  4. ejecute ./manage.py convert_to_south en ambos lados (falsificando la migración 0001)
  5. entonces puedo reiniciar para hacer migraciones y empujar las carpetas de migraciones en mi servidor

* excepto si desea limpiar solo una aplicación entre otras, de ser así, deberá editar su tabla south_history y eliminar solo las entradas sobre su aplicación.


2
Solo para que conste, la respuesta del autor del Sur fue la siguiente: siempre que tenga cuidado de hacerlo en todas las implementaciones simultáneamente, no debería haber ningún problema con esto. Personalmente, haría: rm -r appname / migrations / ./manage.py reset south ./manage.py convert_to_south appname (Tenga en cuenta que la parte "reset south" borra los registros de migración para TODAS las aplicaciones, así que asegúrese de ejecutar las otras dos líneas para todas las aplicaciones o eliminar selectivamente).
Adriaan Tijsseling

2
Tenga en cuenta también que si suelta las tablas, entonces necesita en manage.py schemamigration app name --initiallugar de convert_to_south.
Adriaan Tijsseling

77
A partir de Django 1.5, el comando de administración "restablecer" desapareció. En cambio, querrás hacer algo más o menos como south.models.MigrationHistory.objects.all().delete().
Andrew B.

13
@Dominique: Su consejo sobre manage.py reset southes peligroso y puede destruir la base de datos si hay aplicaciones de terceros que usan el sur en el proyecto, como lo señala @thnee a continuación. Dado que su respuesta tiene tantos votos positivos, realmente lo agradecería si pudiera editarlo y agregar al menos una advertencia al respecto, o (aún mejor) cambiarlo para reflejar el enfoque @hobs (que es igual de conveniente, pero no afectar otras aplicaciones) - ¡gracias!
chrisv

3
¿Por qué fue tan altamente votado? Casi NUNCA debería eliminar por completo su tabla south_migrationhistory. Eso arruinaría por completo cualquier aplicación dependiente con migraciones que no desea tocar. La respuesta de Hob es la correcta.
Cerin

188

Si necesita reiniciar selectivamente (solo una aplicación) las migraciones que están tardando demasiado, esto funcionó para mí.

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

No olvide restaurar manualmente las dependencias de otras aplicaciones agregando líneas como depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))su <app-dir>/migrations/0001_initial.pyarchivo, como el primer atributo en su clase de migración justo debajo class Migration(SchemaMigration):.

Luego puede hacerlo ./manage.py migrate <app-name> --fake --delete-ghost-migrationsen otros entornos, según esta respuesta SO . Por supuesto, si falsifica la eliminación o la falsificación migrate zero, deberá eliminar manualmente las tablas db sobrantes con una migración como esta .

Una opción más nuclear es ./manage.py migrate --fake --delete-ghost-migrationsen el servidor de implementación en vivo seguido de un [my] sqldump. Luego canalice ese volcado en [my] sql en los entornos donde necesita la base de datos migrada y completamente poblada. Sacrificio sur, lo sé, pero funcionó para mí.


2
Lo que realmente quiero es "tomar models.py como gospel y hacerme una limpieza a partir de ese momento". Por lo tanto, conserva la capacidad de configurar una implementación desde cero o trabajar desde una implementación existente.
Bryce

1
Eso es lo que hace esto.
placas el

2
@hobs Estaba un DependsOnUnknownMigrationtiempo fingiendo la nueva migración inicial. Gracias a tu comentario, pude descubrir que debería actualizar la depends_ondeclaración siempre que se refiera a esta aplicación. Esta es realmente la mejor respuesta aquí. ¡Gracias! :)
manu

55

Gracias a las respuestas de Dominique Guardiola y las placas, me ayudó a resolver un problema difícil. Sin embargo, hay un par de problemas con la solución, aquí está mi opinión al respecto.

Usar nomanage.py reset south es una buena idea si tiene aplicaciones de terceros que usan South, por ejemplo django-cms(básicamente todo usa South).

reset south eliminará todo el historial de migración de todas las aplicaciones que haya instalado.

Ahora considere que actualiza a la última versión de django-cms, contendrá nuevas migraciones como 0009_do_something.py. South seguramente se confundirá cuando intente ejecutar esa migración sin tener que 0001pasar 0008por el historial de migración.

Es mucho mejor / más seguro reiniciar selectivamente solo las aplicaciones que está manteniendo .


En primer lugar, asegúrese de que sus aplicaciones no tengan desincronización entre las migraciones en el disco y las migraciones que se han ejecutado en la base de datos. De lo contrario habrá dolor de cabeza.

1. Eliminar el historial de migración de mis aplicaciones

sql> delete from south_migrationhistory where app_name = 'my_app';

2. Eliminar migraciones para mis aplicaciones

$ rm -rf my_app/migrations/

3. Crear nuevas migraciones iniciales para mis aplicaciones

$ ./manage.py schemamigration --initial my_app

4. Falso ejecutar las migraciones iniciales para mis aplicaciones

Esto inserta las migraciones south_migrationhistorysin tocar las tablas reales:

$ ./manage.py migrate --fake my_app

Los pasos 3 y 4 en realidad son solo una variante más larga de manage.py convert_to_south my_app, pero prefiero ese control adicional, en una situación tan delicada como la modificación de la base de datos de producción.


2
Edité mi respuesta para incorporar soluciones a los problemas que encontraste (solo adivinando en función de tu respuesta), y lo probé en una base de datos de producción con millones de filas.
Hobs

2
Esto es más o menos lo que estamos haciendo. Si usa la opción --delete-ghost-migrations en el paso 4, puede omitir el paso 1.
tobych

Debe especificar los nombres de las aplicaciones explícitamente ./manage.py migrate --fakesi no desea falsificar la migración de otras aplicaciones que tienen migraciones pendientes.
wadim

2
@wadim Por lo tanto, paso 0: "asegúrese de que no tiene desincronización entre las migraciones en el disco y las migraciones que se han ejecutado en la base de datos".
Thnee

@thnee Right. Probablemente valga la pena mencionar que se refiere a todas las aplicaciones instaladas en el paso 0. Sin embargo, ¿conoce una manera fácil de realizar el paso 0?
wadim

7

Al igual que Thnee (vea su respuesta), estamos utilizando un enfoque más suave para la sugerencia del autor del Sur (Andrew Godwin) citada en otro lugar aquí, y estamos separando lo que hacemos con la base de código de lo que hacemos a la base de datos, durante el despliegue , porque necesitamos que las implementaciones sean repetibles:

Lo que hacemos en el código:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

Lo que hacemos a la base de datos una vez que se implementa el código

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

Creo que hice lo mismo, pero eliminé manualmente las entradas de la base de datos, en lugar de usar --delete_ghoist-migrations. Tu camino es un poco más agradable.
wobbily_col 01 de

1

Si solo está trabajando en la máquina de desarrollo, escribí un comando de administración que hace más o menos lo que Dominique sugirió.

http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

En contraste con la sugerencia del autor del sur, esto NO DAÑARÁ otras aplicaciones instaladas que usan el sur.


Y si, a diferencia del autor, desea mantener las migraciones existentes (es decir, desea restablecer la aplicación y el historial de migración, pero mantener las migraciones reales), puede intentar esto: goo.gl/0ZnWm
mgalgs

1

Lo siguiente es solo si desea restablecer todas las aplicaciones. Haga una copia de seguridad de todas sus bases de datos antes de ese trabajo. También tome nota de su dependen_on en los archivos iniciales si hay alguno.

Por una vez:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

Pruebe bootstrapping su proyecto antes de empujar. Luego, para cada máquina local / remota, aplique lo siguiente:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

Haga iniciales (3) para cada aplicación que quiera volver a involucrar. Tenga en cuenta que reset (6) eliminará solo el historial de migración, por lo tanto, no es perjudicial para las bibliotecas. Las migraciones falsas (7) retrasarán el historial de migración de cualquier aplicación de terceros instalada.


0

eliminar el archivo necesario de la carpeta de la aplicación

ruta de instancia

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

wiki -es mi aplicación

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.