Search code examples
pythondjangodjango-testingdjango-tests

Django testing hangs with --keepdb flag


For performance tuning reasons, I want to run Django tests against a copy of my production database. As I understand it, this should be possible by:

(1) adjusting Django settings like

DATABASES = {
    'default': {
        ...
        'TEST': {
            'NAME': 'my_database_copy',
        },
    }
}

and (2) using the --keepdb flag, as in python manage.py test --keepdb.[1]

But when I do this, the process hangs, looking like this:

bash-4.2$ python manage.py test --keepdb
Using existing test database for alias 'default'...

(The process won't close with ctrl+c. I'm using Docker, and I stop it by restarting Docker.)

There are no unapplied migrations for the database, and the test command (python manage.py test) works fine, if --keepdb is omitted.

I confirmed that the database copy is properly restored and accessible because I can access it when I run python manage.py shell.

[1] https://docs.djangoproject.com/en/3.1/topics/testing/overview/#preserving-the-test-database


Solution

  • Adjust the settings dictionary by adding the SERIALIZE key, like this:

    DATABASES = {
        'default': {
            ...
            'TEST': {
                'NAME': 'my_database_copy',
                'SERIALIZE': False,
            },
        }
    }
    

    When SERIALIZE is True (the default), Django tries to read a copy of the whole database into memory as a string. See[1]. This considered helpful for tests when the database engine does not support transactions, but in my case crashed due to insufficient memory. Deactivating this behavior through settings is covered here[2].

    [1] https://github.com/django/django/blob/d5b526bf78a9e5d9760e0c0f7647622bf47782fe/django/db/backends/base/creation.py#L73

    [2] https://docs.djangoproject.com/en/3.1/ref/settings/#serialize