Move Django model from one app to another [duplica

2020-02-11 03:19发布

问题:

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).

回答1:

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.



回答2:

I did something similar on a smaller scale recently and this was my process:

  1. Create new app and corresponding models
  2. Update views to use new models
  3. Update unit/systems tests to make sure nothing broke (important!)
  4. Write a management command that populates the new models based on the old models
  5. Deploy code
  6. Run migration for new models
  7. Run management command script to update new models
  8. Leave old app for 1-2 weeks and when you think its all good, drop them.

The reasons why I didnt use data migration:

  1. Not familiar -- felt the task was too important to use a process I wasn't familiar with
  2. More comfortable moving data with python code then with South magic
  3. 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
  4. 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


回答3:

The simplest solution I could think of:

  1. 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);
  2. Create the new apps and their models normally;
  3. Do a data migration from the old tables to the new ones;
  4. Create another SchemaMigration, changing every primitive type to a foreign key again, now pointing to the new tables;
  5. 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.