Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if merge migration is required, without database

To check if merge migrations are required, I can run manage.py makemigrations --check or manage.py makemigrations --dry-run

However, both of those require the database to be up. If it's not up, it will error out with something like

django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)")

Theoretically, since a merge migration issue occurs because of two migration with the same parent, you don't need the database instance to be up to check for this condition.

I need this because I want my CI to check for this case. I can spin up a docker database but it's extra work for something that's not even logically dependent. I'm also sure there are people out there who are interested in checking for this in their CI, who don't want to deal with containerization.

Has anyone found an easy way to to check for migration merge conflicts without needing a database up?

like image 229
wonton Avatar asked Sep 11 '17 18:09

wonton


People also ask

What does Makemigrations do in Django?

makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database.

Where are Django migrations stored?

Migrations are generated per app, and are stored in some_app/migrations . Even if you do not define migrations for your apps, there will usually be migrations that take place, since you (likely) included some apps defined by Django (and other third parties) in your INSTALLED_APPS , these have migrations as well.

What does Python manage PY migrate do?

migrate executes those SQL commands in the database file. So after executing migrate all the tables of your installed apps are created in your database file.


1 Answers

Since the goal is to run makemigrations --dry without a mysql database up, the easiest workaround I came up with is to create a new settings file called makemigrations_settings.py that overrides the database to use the builtin sqlite database.

from your_main_settings import *
DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'database_name',
        'USER': 'your_mom',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
}

Then you can run

python manage.py makemigrations --check --settings yourapp.makemigrations_settings

Alternatively, you can less elegantly do something like

if (sys.argv[0:2] == ['manage.py', 'makemigrations']
    and ('--dry-run' in sys.argv or '--check' in sys.argv)):
            DATABASES = {
                'default' : {
                    'ENGINE': 'django.db.backends.sqlite3',
                    'NAME': 'database_name',
                    'USER': 'your_mom',
                    'PASSWORD': '',
                    'HOST': '',
                    'PORT': '',
                }
            }
like image 140
wonton Avatar answered Sep 30 '22 05:09

wonton