154 votes

Quelle est l'approche recommandée pour réinitialiser l'historique des migrations à l'aide de Django South ?

J'ai accumulé pas mal de migrations en utilisant South (0.7) et Django (1.1.2) qui commencent à consommer pas mal de temps dans mes tests unitaires. Je voudrais réinitialiser la base de référence et commencer un nouvel ensemble de migrations. J'ai passé en revue le Documentation sur le sud J'ai effectué les recherches habituelles sur Google/Stackoverflow (par exemple, "django south (reset OR delete OR remove) migration history") et je n'ai rien trouvé d'évident.

Une approche que j'ai envisagée consisterait à "recommencer" en "supprimant" South ou en "effaçant" l'historique manuellement (par exemple, en effaçant la table de la base de données, en supprimant les fichiers de migration du directeur des migrations) et en procédant à une nouvelle exécution,

./manage.py schemamigration southtut --initial

Donc, si quelqu'un a déjà fait cela et a des conseils/suggestions, ils seraient grandement appréciés.

188voto

hobs Points 3020

Si vous avez besoin de réinitialiser sélectivement (pour une seule application) les migrations qui prennent trop de temps, este a fonctionné pour moi.

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

N'oubliez pas de restaurer manuellement tout Dépendances sur d'autres applications en ajoutant des lignes comme depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial")) à votre <app-dir>/migrations/0001_initial.py comme premier attribut de votre classe de migration, juste en dessous de class Migration(SchemaMigration): .

Vous pouvez alors ./manage.py migrate <app-name> --fake --delete-ghost-migrations sur d'autres environnements, par cette réponse SO . Bien sûr, si vous faites semblant de supprimer ou de faire semblant de migrate zero vous devrez supprimer manuellement toutes les tables restantes avec une migration telle que este .

Une option plus nucléaire consiste à ./manage.py migrate --fake --delete-ghost-migrations sur le serveur de déploiement en direct, suivi d'un [my]sqldump. Passez ensuite ce dump dans [my]sql sur les environnements où vous avez besoin de la base de données migrée et entièrement remplie. Je sais que c'est un sacrilège du Sud, mais ça a marché pour moi.

122voto

Dominique Guardiola Points 2415

EDIT - Je mets un commentaire en haut de cette page car il est important de le lire avant la réponse > acceptée qui suit @andybak.

@Dominique : Votre conseil concernant manage.py reset south est dangereux et peut détruire la base de données s'il y a des applications tierces qui utilisent south dans le projet, comme l'a souligné @thnee ci-dessous. Puisque votre réponse a tant de votes positifs que j'apprécierais vraiment que vous la modifiiez l'éditer et ajouter au moins un avertissement à ce sujet, ou (encore mieux) la modifier pour refléter l'approche de @hobs (qui est tout aussi pratique, mais qui n'affecte pas les autres applications). d'autres applications) - merci ! - chrisv 26 Mar '13 à 9:09

La réponse acceptée suit ci-dessous :

D'abord, une réponse de l'auteur du Sud :

Tant que vous prenez soin de le faire sur tous les déploiements simultanément, il ne devrait pas y avoir de problème. Personnellement, je le ferais :

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

(Notez que le " reset south La partie "efface les enregistrements de migration pour TOUTES les applications, donc assurez-vous d'exécuter les deux autres lignes pour toutes les applications ou de les supprimer de manière sélective).

El convert_to_south à la fin, crée une nouvelle migration et fait semblant de l'appliquer (puisque votre base de données a déjà les tables correspondantes). Il n'est pas nécessaire de supprimer toutes les tables de l'application pendant le processus.

Voici ce que je fais sur mon serveur de développement + production lorsque je dois me débarrasser de toutes ces migrations de développement inutiles :

  1. Assurez-vous que nous avons le même schéma de base de données des deux côtés.
  2. supprimer tous les dossiers de migrations des deux côtés
  3. exécuter ./manage.py reset south (comme le dit le post) sur les deux côtés = efface la table sud *
  4. exécuter ./manage.py convertir_en_sud des deux côtés (falsification de la migration 0001)
  5. ensuite je peux redémarrer pour faire les migrations et pousser les dossiers de migrations sur mon serveur.

* sauf si vous voulez nettoyer une seule application parmi d'autres, dans ce cas vous devrez éditer votre table south_history et supprimer uniquement les entrées concernant votre application.

55voto

thnee Points 1356

Grâce aux réponses de Dominique Guardiola et de hobs, cela m'a aidé à résoudre un problème difficile. Cependant, il y a quelques problèmes avec la solution, voici ce que j'en pense.

Utilisation de manage.py reset south est pas une bonne idée si vous avez applications tierces qui utilise South, par exemple django-cms (en fait, tout utilise le Sud).

reset south supprimera l'historique des migrations pour toutes les applications que vous avez installées.

Considérons maintenant que vous mettez à jour la dernière version de django-cms il contiendra de nouvelles migrations comme 0009_do_something.py . South sera sûrement confus lorsque vous essayez d'exécuter cette migration sans avoir 0001 par le biais de 0008 dans l'histoire de la migration.

Il est bien mieux/sécurisé de réinitialiser de manière sélective uniquement les applications qui vous maintenez .


Tout d'abord, assurez-vous que vos applications n'ont pas de désynchronisation entre les migrations sur le disque, et les migrations qui ont été exécutées sur la base de données. Sinon, il y aura des maux de tête.

1. Supprimer l'historique de migration de mes applications

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

2. Supprimer les migrations pour mes applications

$ rm -rf my_app/migrations/

3. Créer de nouvelles migrations initiales pour mes applications

$ ./manage.py schemamigration --initial my_app

4. Fake exécute les migrations initiales pour mes applications.

Cela insère les migrations dans south_migrationhistory sans toucher aux tableaux réels :

$ ./manage.py migrate --fake my_app

Les étapes 3 et 4 sont en fait juste une variante plus longue de manage.py convert_to_south my_app mais je préfère ce contrôle supplémentaire, dans une situation aussi délicate que la modification de la base de données de production.

7voto

Toby Champion Points 1453

Comme Thnee (voir sa réponse), nous utilisons une approche plus douce de la suggestion de l'auteur de South (Andrew Godwin) citée ailleurs ici, et nous séparons ce que nous faisons avec la base de code de ce que nous faisons à la base de données, pendant le déploiement, parce que nous avons besoin que les déploiements soient répétables :

Ce que nous faisons dans le code :

# 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

Ce que nous faisons à la base de données une fois que le code est déployé.

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

1voto

idanzalz Points 1170

Si vous ne travaillez que sur la machine de développement, j'ai écrit une commande de gestion qui fait à peu près ce que Dominique a suggéré.

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

Contrairement à la suggestion de l'auteur de south, cela ne nuira PAS aux autres applications installées utilisant south.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X