Migration files created outside project directory (Docker container)

I have a strange problem in a Django container where makemigrations creates the migration files in /usr/local/lib/python3.*/site-packages/*/migrations/ instead of the usual project’s directory (which is bind mounted to the host). When I run makemigration on the host, it creates the migration files in the project as expected.

When I run python manage.py makemigrations inside the container, the output is as follows:

Migrations for 'account':
/usr/local/lib/python3.8/site-packages/allauth/account/migrations/0003_auto_20210818_0316.py
    - Alter field id on emailaddress
    - Alter field id on emailconfirmation
Migrations for 'django_celery_beat':
/usr/local/lib/python3.8/site-packages/django_celery_beat/migrations/0016_auto_20210818_0316.py
    - Alter field id on clockedschedule
    - Alter field id on crontabschedule
    - Alter field id on intervalschedule
    - Alter field id on periodictask
    - Alter field id on solarschedule
Migrations for 'socialaccount':
/usr/local/lib/python3.8/site-packages/allauth/socialaccount/migrations/0004_auto_20210818_0316.py
    - Alter field id on socialaccount
    - Alter field id on socialapp
    - Alter field id on socialtoken 

This is a problem because the migration files are discarded each time the Django container restarts. Consequently, Django thinks I need to run makemigrations and displays a warning/error message each time I restart the container. When I run showmigrations, all the migrations have been applied to the database. Essentially, this is just a nuisance error in our local development environment, but I need to get my container creating the migrations files in the project directory issue before rolling this into production. If someone with more Django/Python knowledge could assist, I would really appreciate it!

The issue here is that your makemigrations is making migrations for system library files. And, I’m guessing these are being created as part of a Django < 3.2 → Django 3.2 migration, where the default primary key has changed from an AutoField to BigAutoField.

If you can’t recreate your tables / database from scratch with the DEFAULT_AUTO_FIELD, you can prevent these migrations from being created by:

  • remove those apps from your INSTALLED_APPS setting
  • create an apps.py file for the affected apps.
    • For example, part of one of my apps.py files looks like this:
from django.apps import AppConfig

class CasNg(AppConfig):
    name = 'django_cas_ng'
    default_auto_field = 'django.db.models.AutoField'

class CeleryBeat(AppConfig):
    name = 'django_celery_beat'
    default_auto_field = 'django.db.models.AutoField'
  • add the new AppConfig models to your INSTALLED_APPS setting.
    • For example, the entries in my INSTALLED_APPS for those corresponding apps are:

    ‘project.apps.CasNG’,
    ‘project.apps.CeleryBeat’,

(There may be other ways of handling this, but this is how we settled on it.)

Hi Ken,

Thanks a bunch for pointing me in the right direction! This is the first non-toy project where I’ve used Django. You were right about the cause being the <3.2 to 3.2 upgrade. I tested the same code in a Django 3.1 container and migrations worked perfectly. I ended up setting DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField', so I can take advantage of the new larger PK. I upgraded django-celery-beat to the latest version, which has recently been updated to support Django 3.2. That eliminated celery beat’s migration issue. After that, my only problem was with all-auth which hasn’t been updated to support BigAutoField yet. Because of that, I took your advice and put an override in the app.py which now works.

Thank you so much for taking the time to help me fix this issue. I hate to think how many days or weeks I would have burned trying to figure this out being a Django newbie.

PS - I’m not certain if this is the best approach. Someone please chime in if it would be better to simply set DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'. Even though I’ve developed lots of web apps, my Django experience is very limited. Maybe I’m setting myself up for something suboptimal down the road.