3

I'm working on upgrading my legacy application from Django 1.11.13 to 2.2.8. I've dutifully addressed every compatibility issue, but I've hit one I can't figure out how to resolve. When I try to start the webserver in my local environment, I get this error (only showing the end of the full error trace that appears):

  File "/Users/me/my_app/my_model/migrations/0001_initial.py", line 37, in Migration
    ('entry', models.ForeignKey(to='my_model.Entry')),
TypeError: __init__() missing 1 required positional argument: 'on_delete'

I understand why on_delete is now required -- I just spent a while updating my models everywhere to accommodate this change -- but I have no idea how to fix this particular issue without going through dozens of old migrations files to make them conform?!

  • I tried squashmigrations to at least collapse the number of places I have to clean up, but I got the same exact TypeError.

  • I tried to use the old version of Django for squashmigrations. I was successful in avoiding the TypeError, but ended up with a huge mess of circular import errors.

  • Since I don't actually need the migration history to roll back, I tried to follow these instructions (scenario 2) to clear the migration history while keeping the existing database, but I couldn't run makemigrations to catch up on the changes I made to make my models Django 2.2 compliant, and when I decided I'd skip ahead and deal with that later, showmigrations failed with the same TypeError. (Is there some other way to get a fresh set of initial migrations based on the current database? It can't be based off the models since the models have upgrade-related changes not yet reflected in the database.)

  • I moved the migrations to a non-standard location, which got the server to start, but that makes it impossible to actually do anything migration related ever again, and of course once I move back, everything breaks again...

I've considered just deleting my entire database and all migration history, building the tables from scratch with a fresh set of initial migrations, and then resetting the data from a backup, but there are a few huge tables which would make this take quite a while... and this rather seems like the nuclear approach. Am I stuck with editing a large number of very old migrations to be compliant with Django 2.2 for no actual reason since I'm never going to roll my project that far back? How can that be right?

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
TAH
  • 1,658
  • 1
  • 19
  • 37
  • Can you roll back to the version that was working - squash migrations - then upgrade? – Iain Shelvington Dec 10 '19 at 05:34
  • That was the second thing I tried. Attempting to squash migrations created a mess of circular import errors that seems even more unpleasant to untangle than editing old migration files... – TAH Dec 10 '19 at 05:37
  • 1
    One option is to delete all of your migration files, then run makemigrations with the "on_delete" fixes - this should create some "initial" migration files. Then you'll have to log in to your DB and delete all entries for your apps and then you run `manage.py migrate --fake` - this will enter into the DB entries for the newly created migrations but will not apply them – Iain Shelvington Dec 10 '19 at 05:41
  • That worked with a slightly different order -- I had to delete all the migration files *and* all the entries in the db connected to those migrations to get `makemigrations` to create the initial files. (With no files & the db in tact, it insisted, "No changes detected.") Thank you! – TAH Dec 10 '19 at 05:48
  • 1
    No worries glad it helped – Iain Shelvington Dec 10 '19 at 05:54
  • Deleting migrations is _not_ the appropriate solution here, as it would break in production - the correct approach is provided in the question that I've marked this as a duplicate of - which is to modify the existing migrations to include the `on_delete` parameter. – solarissmoke Dec 10 '19 at 08:23
  • Hi TAH. Please allow me to explain the edit here. We get a lot of questions come in every day, and many of them are accompanied by great tales of woe and suffering that volunteer helpers need to wade through. Some of them are of such pleading intensity that readers are not just asked to "please help me", but that the poster is in a state of distress: "I am desperate" or "Stack Overflow is my last hope" or "I am about to lose my job" etc etc. – halfer Apr 27 '20 at 11:24
  • "I am at my wits end" is a powerful statement of woe, and indicates that the speaker is about to lose their wits - i.e. their sanity - as a result of their well-advertised suffering. The purpose of this verbiage is to place the reader under a social obligation to relieve that suffering, which seems to be an unfair burden to place on volunteers. This can encourage readers to take on more help than they have time or energy for. – halfer Apr 27 '20 at 11:26
  • So, the community preference is to not add these, and to stick to technical writing. Moreover, there is no value in keeping such material in questions, since it is just extra fluff for readers to wade through. – halfer Apr 27 '20 at 11:28

1 Answers1

2

As Iain Shelvington mentions in a comment under the question,

First delete all of your migration files and folder, then run makemigrations with the "on_delete" - this should create some "initial" migration files. Then you'll have to log in to your DB and delete all entries for your apps and then you need to run manage.py migrate --fake - this will enter into the DB entries for the newly created migrations but will not apply them

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Hamza Lachi
  • 1,046
  • 7
  • 25