Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renaming an app with Django and South

I am renaming an application to a more suitable name. In doing so, I want to ensure that South properly migrates the database (renames database tables and changes references in django_content_type or south_migrationhistory). I know how to migrate a model to a different app, but when I try rename the app itself, South does not recognize the migration history properly.

Undesirable solution: In renaming old_app to new_app I could leave old_app/migrations intact and add new migrations to this directory to migrate the database to reference new_app.

If possible I would prefer to delete the directory old_app entirely. I have not yet thought of a better solution to this problem.

What is the best way to rename an app with Django South without losing data?

like image 744
Trey Hunner Avatar asked Dec 30 '10 23:12

Trey Hunner


People also ask

Can we rename an app in Django?

Delete the database tables of the app to be renamed. Rename the folder of the app. Change any references to your app in their dependencies, i.e. the app's views.py , urls.py , 'manage.py' , and settings.py files. If your models.py 's Meta Class has app_name listed, make sure to rename that too (mentioned by @will).

Can I rename Django migration file?

If it's a brand new migration, 2 and 3 won't apply, and it's perfectly fine to rename them.


1 Answers

I agree with Laksham that you should avoid this situation. But sometimes, we have to. I've faced this situation in the past and I've managed it this way.

If you want to avoid losing data you can dump the old application data into a json file.

python manage.py dumpdata old_app --natural --indent=4 1> old_app.json 

Note the --natural option that will force the content types to be exported with their natural keys (app_name, model)

Then you can create a small command to open this json file and to replace all the old_app references with the new_app.

Something like this should work

class Command(BaseCommand):     help = u"Rename app in json dump"      def handle(self, *args, **options):         try:             old_app = args[0]             new_app = args[1]             filename = args[2]         except IndexError:             print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'             return          try:             dump_file = open(filename, 'r')         except IOError:             print filename, u"doesn't exist"             return          objects = json.loads(dump_file.read())         dump_file.close()          for obj in objects:             obj["model"] = obj["model"].replace(old_app, new_app, 1)              if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):                 obj["fields"]["content_type"][0] = new_app          dump_file = open(filename, 'w')         dump_file.write(json.dumps(objects, indent=4))         dump_file.close() 

Then rename the application, change the name in INSTALLED_APPS.

Then, you should remove all south migrations, regenerate and apply an initial migration for the new app. Then run the SQL command:

update django_content_type set app_label='new_app' where app_label='old_app' 

Then launch a south migrate for the new app in order to create the tables and load the json file.

python manage.py loaddata old_app.json 

I've done something similar on a project and it seems to work ok.

I hope it helps

like image 69
luc Avatar answered Sep 16 '22 15:09

luc