2013-06-25 5 views
1

Supposons que vous développiez sur un projet Django avec quelques personnes utilisant (par exemple) git. Quand vous faites git pull vous pourriez avoir quelques migrations du sud, cependant, vous pourriez ne pas remarquer (pour une raison quelconque). Ensuite, lorsque vous continuez à développer, vous pouvez rencontrer des exceptions python car vous n'avez pas effectué les migrations. Maintenant, il peut parfois être un peu de temps avant de découvrir que vous avez oublié cela, ce qui est assez ennuyeux. Par conséquent, je pensais que South ne pouvait pas détecter que vous n'aviez pas fait toutes les migrations et juste lancer une exception si oui?Django Sud - Un moyen de détecter si la migration vers le sud doit être effectuée?

J'imagine que cela pourrait être un paramètre que vous pourriez désactiver si vous voulez continuer à développer sans faire la migration.

+0

j'ai trouvé un article qui décrit comment détecter si programatically au sud a des migrations à courir (http://rochacbruno.com.br/programatically-check- if-you-south-have-migrations-to-run /). Je pourrais convertir cela en middleware que j'ajouterai dans mes paramètres de développement. Je vais répondre à ma propre question si je parviens à le faire. – rednaw

Répondre

1

Ok, j'ai fait un middleware qui fait ce que je veux. Lorsque vous faites une demande, elle vérifie quelles migrations vous n'avez pas encore appliquées et déclenche une exception. Assurez-vous d'utiliser ce middleware uniquement en développement!

Vous pouvez également trouver la source sur https://gist.github.com/gitaarik/5974176

from south import migration 
from south.models import MigrationHistory 


class SouthUnranMigrationCheck(object): 

    def process_request(self, request): 
     ''' 
     Checks if you ran all South migrations. If not, it will throw an 
     exception (DidNotApplyAllMigrations). 
     ''' 

     unapplied_migrations = self.unapplied_migrations() 

     if len(unapplied_migrations) > 0: 

      message = u'You haven\'t run the following migrations: {}'.format(
       u''.join(
        [u'\n "{}" in app "{}".'.format(name, app) 
        for name, app in unapplied_migrations] 
       ) 
      ) 

      raise DidNotApplyAllMigrations(message) 

    def unapplied_migrations(self): 
     ''' 
     Returns a list of tuples of unapplied migrations. The tuples consist of 
     a migration name and an app label. 
     ''' 

     applied_migrations = self.applied_migrations() 
     unapplied_migrations = [] 

     for app_migration_files in migration.all_migrations(): 

      for migration_file in app_migration_files: 

       app_label = migration_file.app_label() 
       migration_name = migration_file.name() 

       if migration_name not in applied_migrations[app_label]: 
        unapplied_migrations.append((migration_name, app_label)) 

     return unapplied_migrations 

    def applied_migrations(self): 
     ''' 
     Returns a dictionary with the app name in the key, and a list of 
     migrations in the value. 
     ''' 

     applied_migrations = {} 

     for applied_migration in MigrationHistory.objects.all(): 

      if applied_migration.app_name not in applied_migrations: 
       applied_migrations[applied_migration.app_name] = [] 

      applied_migrations[applied_migration.app_name].append(
       applied_migration.migration) 

     return applied_migrations 


class DidNotApplyAllMigrations(Exception): 
    ''' 
    Exception that indicates that you havent run all migrations. 
    ''' 
    pass 
+1

Quoi? pourquoi la downvote? S'il vous plaît, expliquez. – rednaw

3

ok, c'est mon chemin.

J'ai une application south_test avec 3 migrations, qui est le'python manage.py migrer --list' montre:

south_test 
    (*) 0001_initial 
    (*) 0002_auto__add_person 
    () 0003_auto__add_field_person_age 

qui est (pas trop) code magique:

from south.models import MigrationHistory 
from south.migration import Migrations 

all_migrations = Migrations('south_test') 
applied_migrations = MigrationHistory.objects.filter(app_name='south_test') 

not_applied = list(set(all_migrations) - set([migration.get_migration() for migration in applied_migrations])) 

Vous avez maintenant not_applied migrations. Peut-être qu'il y a quelques détails avec les migrations de fantômes. Voir la commande migrate du sud pour les détails.

Espérons que cela aide!

+0

Merci lalo. En fin de compte, j'ai créé mon propre middleware qui résout mon problème. Vérifie ma réponse – rednaw

Questions connexes