Search code examples
djangodjango-modelsdjango-migrations

Django makemigrations KeyError: 'content_type'


Last time I changed the data model locally and tried to push it to production and migrate the database there I've got the following response from the makemigrations command:

    Traceback (most recent call last):
      File "manage.py", line 15, in <module>
        execute_from_command_line(sys.argv)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
        utility.execute()
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/base.py", line 330, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/base.py", line 371, in execute
        output = self.handle(*args, **options)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/base.py", line 85, in wrapped
        res = handle_func(*args, **kwargs)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 201, in handle
        pre_migrate_state = executor._create_project_state(with_applied_migrations=True)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/db/migrations/executor.py", line 79, in _create_project_state
        migration.mutate_state(state, preserve=False)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/db/migrations/migration.py", line 87, in mutate_state
        operation.state_forwards(self.app_label, new_state)
      File "/home/JoshuaMSchmidt/.virtualenvs/env/lib/python3.7/site-packages/django/db/migrations/operations/fields.py", line 158, in state_forwards
        old_field = model_state.fields.pop(self.name)
KeyError: 'content_type'

Now I am not able to move forward or backwards and am stuck with the current data model on the server. Can I somehow drop all old migration files from the production server and start again clean from the current database?

To be honest I am not really sure what the Error means

Happy to supply additional Information as I also dont really know where to start.


Solution

  • if you see the following line in the traceback

     pre_migrate_state = executor._create_project_state(...)
    

    It is even not related to the type of the database backend (sqlite3 vs MySQL vs PostgreSQL), but to the code of the project. Then you can reproduce the problem and solve if safely in another development virtual Python environment first where you can start with an empty database. Maybe all code is not exactly the same (a file not tracked by a repository?) or the migrations were created in a higher Django version than is running on production (e.g. 3.2.x vs. 3.1.x) or INSTALLED_APPS are different or you removed some unused part of code too soon that is still used by some migration.


    A general troubleshooting for migrations:

    Run the command python manage.py showmigrations to see all unapplied migrations. (You can also compare it with the same list on the development machine. That could reveal e.g. an incompatible configuration.)


    Run a command python manage.py migrate --plan to see a simple information what is the content of the first failed not applied migration. Read the first line. Example:

    Planned operations:
    example.0003_auto_20210714_2108
        Add field foo_field to my_model
        Add field bar_field to my_model
    

    Verify by some database management application that the first command has not been applied yet (e.g. the "foo_field" is not added) to be sure that the database state is still consistent.


    Split a problematic migration on a development machine to two or more smaller migrations:

    Delete the migration file (by moving it to some backup)

    Guess what can be the problematic change and that is simple. (It is removing a field "content_type" in your case or removing a GenericForeignKey that use a content_type and maybe also something that was used by it.) Revert all problematic changes in models.py, run "manage.py check" and run "manage.py makemigrations". Apply other problematic changes one by one and run check and makemigrations after every change. Try these migrations forwards and backwards in development. Replace the problematic unapplied big migration in production by them.