Django 1.11 + py.test:解决测试访问非托管外部库/表的ConnectionDoesNotExist错误
解决pytest测试Django非托管模型时的ConnectionDoesNotExist问题
咱们先理清楚问题的核心:你用了managed=False的非托管模型,测试时需要访问已有数据库,但pytest-django没正确加载指定的my_connection_name连接,加上之前的fixture可能时机或配置不对,导致没生效。下面给你几个可行的解决思路:
1. 先确保数据库配置正确加载
首先检查你的settings.py,确保my_connection_name的数据库配置在测试环境下是正确的,并且明确测试时不创建新库、不执行迁移:
# settings.py DATABASES = { 'default': { # 你的默认数据库配置 }, 'my_connection_name': { 'ENGINE': 'django.db.backends.mysql', # 替换成你的数据库引擎 'NAME': 'your_legacy_db_name', 'USER': 'test_user', 'PASSWORD': 'test_password', 'HOST': 'localhost', 'PORT': '3306', 'TEST': { 'NAME': 'your_legacy_db_name', # 直接使用已有数据库,不新建测试库 'MIGRATE': False, # 禁止测试时运行迁移 } } }
2. 调整conftest.py的fixture,确保时机和配置正确
之前的fixture可能在模型未完全加载时就执行了,或者没指定数据库连接。你可以修改成这样,确保先激活目标连接,再修改非托管模型的属性:
# conftest.py import pytest from django.apps import apps from django.db import connections @pytest.fixture(autouse=True, scope='session') def setup_unmanaged_models(): # 先显式激活目标数据库连接,确保连接存在 conn = connections['my_connection_name'] if not conn.is_usable(): conn.connect() # 找到所有非托管模型,修改它们的managed属性并指定数据库 unmanaged_models = [m for m in apps.get_models() if not m._meta.managed] for model in unmanaged_models: model._meta.managed = True # 显式绑定模型到目标数据库连接 model._meta.db = 'my_connection_name'
3. 在测试中明确指定要使用的数据库
pytest-django的@pytest.mark.django_db支持指定databases参数,告诉框架要初始化哪些数据库连接,避免找不到连接的问题:
@pytest.mark.django_db(databases=['my_connection_name']) def test_example_access(): from example.models import Example Example.objects.count()
4. 给非托管模型显式指定数据库连接
你也可以直接在模型的Meta类里指定数据库连接,这样Django就能明确知道模型属于哪个数据库:
class Example(models.Model): # 你的字段定义 class Meta: managed = False db_table = 'example_table' # 对应已有数据库中的表名 db = 'my_connection_name' # 显式指定数据库连接
5. 参考legacy数据库测试的变通方案,添加连接激活fixture
如果还是有问题,可以单独写一个fixture来确保测试前数据库连接是可用的:
# conftest.py @pytest.fixture(scope='function') def legacy_db(): from django.db import connections conn = connections['my_connection_name'] # 确保连接可用 if not conn.is_usable(): conn.connect() yield conn # 测试结束后回滚事务(如果需要) conn.rollback()
然后在测试中使用这个fixture:
@pytest.mark.django_db(databases=['my_connection_name']) def test_example_access(legacy_db): from example.models import Example Example.objects.count()
这些步骤应该能帮你解决ConnectionDoesNotExist的问题,你可以根据自己的实际情况调整~
内容的提问来源于stack exchange,提问作者elke
相关产品推荐
相关产品推荐

