2

I have a django app which consists of 17 models. Now I have realized that these models should be in 3 different apps(not in the original app). So now I would like to migrate these models out of the original app to these 3 different apps. How do I do that?

There exists foreign key, generic foreign key and ManyToMany relationships among the models. I also have data in the database(MySql), so I would like the data to be preserved during migration.

I have installed south for migrations, but don't know how to use it for solving this issue. I have gone through this similar question but could not find an answer that would solve my problem. Would be thankful for any help !

Community
  • 1
  • 1
Santosh Ghimire
  • 2,811
  • 8
  • 31
  • 58

1 Answers1

2

In my opinion, you have two ways of completing this task as stated below:

  1. Move the models and add Meta.db_table to refer the existing sql table as needed as @kroolik suggested
  2. Perform a three steps migration

The former is easier while the later could be better as tables would be named as you expect.

First of all, you mention you already has south installed. The first step would be to create the initial migration for the existing app. Take a look to the south tutorial. Then you must apply that migration, but as you already has the tables in db it would fail unless you include --fake flag.

After that you need to create the three apps you mention, and their models. Also create and apply (this time without fake flag) the initial migration for them.

Next step is write a datamigration. You must write it manually, although you can create the skeleton with datamigration. You must write "by hand" the migration.

Now you are almost done, the only remaining thing is remove the original tables. You can just remove those models, and create an "auto" schemamigration.

Don't forget to apply the migrations with migrate command. Also as @Bibhas mention a copy of database and/or a dump of it is a pretty good idea.

Santosh Ghimire
  • 2,811
  • 8
  • 31
  • 58
esauro
  • 1,268
  • 9
  • 17
  • When I create the three apps, and their models, I kept the models of original app as it is. And applying initial migration to one of the three apps(Notification), I get a long error: CommandError: One or more models did not validate: Notification.notification: Accessor for field 'notification_from' clashes with r elated field 'User.from'. Add a related_name argument to the definition for 'not ification_from'. And when I do that by commenting the models of original app, this error occurs $ python manage.py schemamigration Notification --initial ImportError: cannot import name Notification – Santosh Ghimire Oct 10 '13 at 05:23
  • I guess you have a circular import issue. This happens when you import module A from module B and module B from module A. You could remove the imports and use strings in ForeignKey constructors as stated in [django docs](https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey) – esauro Oct 10 '13 at 05:44
  • It was not a circular import issue. The issue was with related_name(didn't supply related_name argument in the models). – Santosh Ghimire Oct 10 '13 at 07:04
  • Should I write datamigration for the original app or the three new apps? – Santosh Ghimire Oct 10 '13 at 07:11
  • The datamigration will be used for converting one to three. In my opinion it's better to put it in the original app. – esauro Oct 10 '13 at 08:18
  • I am using mysql and the models are marked for no-dry-run after a migration failed. How do I resolve this now? – Santosh Ghimire Oct 17 '13 at 07:55