After a successful upgrade from Django 1.8 to Django 2.2.4, when I run the tests it fails because Django does not create the database tables.
My test_settings.py file was working appropriately before the upgrade.
after debugging the Django db/backends it looks like the connection was created, but the tables were not. my suspicion is that test_setting.py is not configured well, although I copied everything from the setting.py file except the database configuration (that remained SQLite).
database configuration:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'test_database'
}
}
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'my_app',
'mptt',
'corsheaders',
# audit app
'easyaudit',
'kronos',
'django.contrib.admin',
]
The traceback that I'm getting (here it's, for example, the auth_user, but it reproduces for all the tables the same way):
Traceback (most recent call last):
File "C:\Users\owner\Desktop\workspace\my_project\MyProject\services\tests\test_logging.py", line 33, in setUpClass
cls.user = User.objects.get_or_create(username='logging_test_user', password='test_password')
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\query.py", line 538, in get_or_create
return self.get(**kwargs), False
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\query.py", line 402, in get
num = len(clone)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\query.py", line 256, in __len__
self._fetch_all()
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\query.py", line 55, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\models\sql\compiler.py", line 1100, in execute_sql
cursor.execute(sql, params)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\owner\Desktop\workspace\my_project\venv36\lib\site-packages\django\db\backends\sqlite3\base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: auth_user
The tests getting executed with the environment variables of
DJANGO_SETTINGS_MODULE=MyProject.test_settings
It seems that there is a bug in django in this version (also since 2.2 maybe before, I didn't check more than that).
databases = self.get_databases(suite)
old_config = self.setup_databases(aliases=databases)
databases variable in here wont be None in no case because in the get_databases function it calls to _get_databases() and incase it won't find any databases that got configured like it mention above, databases will set to set(), and that in setup_databases function there's a function called
get_unique_databases_and_mirrors
that check if there's is not database configured in the tests, and if not it will take the databases that configured in the settings file, but because its set to an empty set (set()) than it wont get into this condition, and therefore no database will get created.
to pass that bug, you can create a class that will inherit unittests.Testcase, and configure the database like this:
import django
import unittest
from django.conf import settings
class MyTestCase(unittest.TestCase):
databases = settings.DATABASES
@classmethod
def setUpClass(cls) -> None:
super(MyTestCase, cls).setUpClass()
django.setup()