How to remove a model definition completely in Django when it previously had foreign keys

181 views
Skip to first unread message

Henrik Ossipoff Hansen

unread,
Mar 8, 2019, 9:07:08 AM3/8/19
to Django users
We're trying to remove a model completely from one of our apps - an operation I think we've done many times without issues, but this time it's causing us some headache. Consider we have two apps:

An app called a with a model A
An app called b with a model B, and this model B has a foreign key to A.

This means the initial Django migration file for app b contains an entry for a foreign key to the string 'a.A'. Let's call this step 1.

Now later, we remove the foreign key on model B. This of course creates a new migration, but the initial migration still has the 'a.A' foreign key definition in it (obviously). Let's call this step 2.

Now the tricky part: we want to remove the whole model A. This in itself creates a migration for app a to that deletes the model, but poses a new problem; when running the full migration history (for example during tests), the initial migration of app b will fail, because it can no longer resolve 'a.A'. Let's call this step 3.

How are people coping with the issue the best? One solution I can think of involves doing a migration squash (and would be sort of easy in our case, since we're actually going to remove the whole app a as well), but it seems a bit extreme. Is there anyone out there with a better and less intrusive solution?

Regards,
Henrik Ossipoff Hansen

Clara Daia

unread,
Mar 8, 2019, 9:23:51 AM3/8/19
to Django users
Are you getting an error? I think migration dependencies should solve that by themselves, running "step 2" before "step 3". Doesn't Django complain if you try to migrate "step 3" before "step 2"?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/162da80d-ca64-48d1-b555-4ce44d6040aa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Henrik Ossipoff Hansen

unread,
Mar 8, 2019, 10:06:37 AM3/8/19
to Django users
Yes, when running tests (which happen on a clean database), the migration history is run all from the initial migrations (by Django itself). At this point, app b's initial migration (which have a reference to a.A) will fail because it cannot find such model:

ValueError: Related model 'a.A' cannot be resolved

James Bennett

unread,
Mar 8, 2019, 4:19:23 PM3/8/19
to django...@googlegroups.com
When you need to remove any piece of code that's been referenced in migrations, generally there's a multi-step process.

For sake of a simple example, let's assume you have Model A in App A, and Model B in App B. And at some point you added a foreign key from Model A to Model B, but now you want to completely remove Model B. The process is:

1. Remove the foreign key from Model A and generate a migration for that. Apply the migration. DO NOT DELETE MODEL B'S CODE YET.
2. Generate a migration with a RemoveModel operation for Model B. DO NOT DELETE MODEL B'S CODE YET.
3. Squash migrations for App A, starting at the point the foreign key to Model B was added, and ending at the point the foreign key to Model B was removed. DO NOT DELETE MODEL B'S CODE YET.
4. Now that only a single migration file references Model B, either remove the AddField/RemoveField operations from it entirely, or replace them with migrations.RunPython.noop operations. DO NOT DELETE MODEL B'S CODE YET.
5. Verify that you can bring up a fresh database correctly with the migrations you now have. DO NOT DELETE MODEL B'S CODE YET.
6. Finally: delete Model B's code from your codebase.

if you referred to this model from multiple apps/models, you will need to do steps 1-5 once for each app/model that had a reference.
Reply all
Reply to author
Forward
0 new messages