This question already has answers here:
Closed 6 years ago.
I made the stupid mistake of creating too many models in the same Django app, now I want to split it into 3 distinct ones. Problem is: there's already data in production in two customers' sites, so I need to carefully plan any schema/data migration to be done (I'm using django-south). I'm unsure on how to proceed, any advice would be greatly appreciated.
(I'm using PostgreSQL on a Ubuntu server 12.4 LTS, if that's of any relevance)
I thought about using db.rename_table
, but can't figure out how to correctly update the foreign keys to those models (old to new) - irrelevant at the database level (since the table renaming already got that covered), but not so at the ORM level.
Update: after thinking about it, and after asking this question on programmmers.SE, I decided to keep things simple and don't worry about migrations between major versions of the product. Short term, I'll just use db.rename_table
to match the new name, while also using db_table
as Daniel Roseman suggested, all the while keeping the models in the old app. When upgrading to a major version, I swith to the new app and ditch all migrations altogether (so fresh installs of the new version will create the database "as-is" instead of going through all historical migrations).
I don't see why you need any data migration at all.
Just move the models to the new app, and add a db_table
setting in the inner Meta classes to point to the old table names.
I did something similar on a smaller scale recently and this was my process:
- Create new app and corresponding models
- Update views to use new models
- Update unit/systems tests to make sure nothing broke (important!)
- Write a management command that populates the new models based on the old models
- Deploy code
- Run migration for new models
- Run management command script to update new models
- Leave old app for 1-2 weeks and when you think its all good, drop them.
The reasons why I didnt use data migration:
- Not familiar -- felt the task was too important to use a process I wasn't familiar with
- More comfortable moving data with python code then with South magic
- Ran into south migration issues with dependencies. Didn't want to further complicate the migrations with a data migration. This could will be a mis-founded assumption due to my unfamiliarity with the mechanics of a data migration
- Perhaps as a bias from point 3, I convinced myself using South purely as a schema management tool is the 'right' way to do. Creation/updating of data should be done in the Django layer using either fixtures or custom management commands
The simplest solution I could think of:
- Create a
SchemaMigration
changing the type of every foreign key to models in the old app to a primitive type (including ones internal to it);
- Create the new apps and their models normally;
- Do a data migration from the old tables to the new ones;
- Create another
SchemaMigration
, changing every primitive type to a foreign key again, now pointing to the new tables;
- Remove the old app from settings and drop its tables.
Laborious, yes, but would do the trick. I'd hope for a better solution though.