gpt4 book ai didi

python - 如何跳过在 Django 中创建测试数据库之一

转载 作者:行者123 更新时间:2023-12-03 20:19:29 29 4
gpt4 key购买 nike

我们在 Django 应用程序中使用了两个数据库,一个是“事务性”数据库,一个是“分析性”数据库(用作数据仓库)。 “事务性”模型是使用 Django 模型创建的,“分析性”模型是使用我们的自定义脚本创建的,其中包含“事务性”表的多个连接的原始 sql。

当我们为 django 应用程序运行测试时,两个数据库都会创建它们的测试对应版本,比方说,“test_transactional”和“test_analytical”。 “test_transactional”的创建没问题,但我们希望跳过“test_analytical”的创建,因为它将由我们的自定义脚本创建和填充。

来自 Jenkins 日志的片段:

python manage.py test --keepdb cis.tests.test_views --  
noinput --settings=strainprint.settings.local --verbosity=2
...
Using existing test database for alias 'analytics'
('test_strainprint_analytics')...
...
Synchronizing apps without migrations:
Creating tables...
Creating table django_admin_log
Creating table auth_permission
...

有没有办法在 Django 中实现这一点?我们使用的是 django 1.10。

最佳答案

根据要求,这是我最终实现的。这里的“遗留”数据库是我们要跳过创建的数据库——Django 应该假定它已经存在。

您首先需要添加这个经过轻微修改的测试运行器,project/runner.py:

from django.test.runner import DiscoverRunner
from django.test.utils import get_unique_databases_and_mirrors
from django.db import connections


class LegacyDatabaseRunner(DiscoverRunner):
"""
Test runner that will skip attempting to create any database with LEGACY=True
in its TEST configuration dictionary
"""
def setup_databases(self, **kwargs):
return _setup_databases(
self.verbosity, self.interactive, self.keepdb, self.debug_sql,
self.parallel, **kwargs
)


def _setup_databases(verbosity, interactive, keepdb=False, debug_sql=False, parallel=0, **kwargs):
"""Clone of django.test.utils.setup_databases"""
test_databases, mirrored_aliases = get_unique_databases_and_mirrors()

old_names = []

for db_name, aliases in test_databases.values():
first_alias = None
for alias in aliases:
connection = connections[alias]

# This clause is all that's been added. If the database's TEST configuration
# has LEGACY=True, skip attempting to create the database, and don't add it
# to the list of databases to tear down after testing is complete.
if connection.settings_dict.get('TEST', {}).get('LEGACY', False):
continue

old_names.append((connection, db_name, first_alias is None))

# Actually create the database for the first connection
if first_alias is None:
first_alias = alias
connection.creation.create_test_db(
verbosity=verbosity,
autoclobber=not interactive,
keepdb=keepdb,
serialize=connection.settings_dict.get('TEST', {}).get('SERIALIZE', True),
)
if parallel > 1:
for index in range(parallel):
connection.creation.clone_test_db(
suffix=str(index + 1),
verbosity=verbosity,
keepdb=keepdb,
)
# Configure all other connections as mirrors of the first one
else:
connections[alias].creation.set_as_test_mirror(connections[first_alias].settings_dict)

# Configure the test mirrors.
for alias, mirror_alias in mirrored_aliases.items():
connections[alias].creation.set_as_test_mirror(
connections[mirror_alias].settings_dict)

if debug_sql:
for alias in connections:
connections[alias].force_debug_cursor = True

return old_names

接下来,将其设置为 project/settings.py 中的默认运行程序:

TEST_RUNNER = 'project.runner.LegacyDatabaseRunner'

然后在您的设置中使用 LEGACY=True 标记您想要跳过创建的任何数据库:

    DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': ...,
},
'legacy_db1': {
'ENGINE': 'sql_server.pyodbc',
'NAME': ...,
'TEST': {
'LEGACY': True, # Do not manage this database during tests
},
},
}

然后希望运行 manage.py test 能按预期工作。

请注意,这在运行并行测试时将起作用。我通过修补 ParallelTestSuite.init_worker 并使用 setup_databases 做了一些改进,但它还没有完全发挥作用。

旧答案,可能在紧要关头有用

这不是一种特别安全的方法,因为此配置选项的语义可能会改变,但您可以将一个数据库声明为另一个数据库的“副本”:

DATABASES = {
'default': {
'NAME': 'transactional',
...
},
'analytical': {
'NAME': 'analytical',
...
'TEST': {
'MIRROR': 'default',
},
}
}

MIRROR 配置选项记录在此处:https://docs.djangoproject.com/en/dev/topics/testing/advanced/#testing-primary-replica-configurations

相关的 Django 源代码在这里:https://github.com/django/django/blob/master/django/test/utils.py

关于python - 如何跳过在 Django 中创建测试数据库之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51071355/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com