从1.8升级到2.2.4后,Django无法为单元测试创建表

从1.8升级到2.2.4后,Django无法为单元测试创建表,django,django-models,django-testing,django-settings,django-2.2,Django,Django Models,Django Testing,Django Settings,Django 2.2,在成功地从Django 1.8升级到Django 2.2.4之后 我运行的测试失败,因为Django没有创建数据库表 升级之前,我的test_settings.py文件工作正常 调试Django db/backends后,看起来连接已经创建,但表没有创建。 我怀疑test_setting.py的配置不好,尽管我复制了setting.py文件中的所有内容,但数据库配置仍然是SQLite 数据库配置: DATABASES = { 'default': { 'ENGINE':

在成功地从Django 1.8升级到Django 2.2.4之后 我运行的测试失败,因为Django没有创建数据库表

升级之前,我的test_settings.py文件工作正常

调试Django db/backends后,看起来连接已经创建,但表没有创建。 我怀疑test_setting.py的配置不好,尽管我复制了setting.py文件中的所有内容,但数据库配置仍然是SQLite

数据库配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'test_database'
    }
}
我在这里得到的回溯是,例如,auth_用户,但它以相同的方式复制所有表:

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
使用的环境变量执行测试

DJANGO_SETTINGS_MODULE=MyProject.test_settings

在这条线路的某个地方,需要将测试用例所使用的数据库连接到它们。在实例化测试数据库之前,Django会根据对象列出所有需要的数据库。在此之后,它为它们创建模式

如果将以下行添加到所有测试继承自的基类中,或添加到Django类的每个子类中:

databases = settings.DATABASES

您会发现您的数据库应该实例化。

这个版本中的django似乎也有一个bug,因为2.2可能在之前,我没有检查更多

    databases = self.get_databases(suite)
    old_config = self.setup_databases(aliases=databases)
这里的databases变量在任何情况下都不会为None,因为在get_databases函数中,它调用get_databases,如果它找不到任何如上所述配置的数据库,databases将设置为set,而在setup_databases函数中,有一个函数名为

get_unique_databases_and_mirrors
检查测试中是否未配置数据库,如果未配置,则将获取设置文件中配置的数据库,但由于其设置为空集,因此不会进入此状态,因此不会创建任何数据库

要传递该错误,您可以创建一个继承unittests.Testcase的类,并按如下方式配置数据库:

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()

您是否看到为别名“default”创建测试数据库。。。运行测试时?您的开发/生产数据库是什么?为什么不在你的测试中使用相同的呢?例如,如果您使用PostgreSQL数据库,并使用特定的pg功能(如JSONField),您的测试将失败。我在我的环境中没有看到它,但在我的同事中,它显示了,但仍然会出现相同的错误。我的开发数据库是PostgreSQL。我们不使用JSONField,所以这不是问题。谢谢你,Dylan。稍微更正一下:您需要发送数据库字典本身,而不是发送数据库名称。当设置来自django.conf导入设置时,可以通过发送settings.DATABASES使其成为通用设置
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()