You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pytest搭建Django测试数据库时触发‘无效对象名’错误

Django + Pytest 测试外部数据库模型时的表不存在错误

更新: 已解决

我尝试使用Pytest对Django应用进行单元测试,但在与Django数据库模型交互时遇到问题。应用中的多数模型设置了managed=False,因为它们连接的是外部数据库。由于之前创建的测试数据库没有任何内容,我使用脚本在运行测试时将这些模型的managed设置为True。

问题在于,每当运行需要数据库访问的测试、系统开始创建测试数据库时,一旦遇到被改为managed=True的模型对应的表,就会抛出错误。查看Pytest的详细回溯信息,系统似乎试图查询测试数据库中对应表的全部内容,但因表不存在而失败。

只有当一个或多个外部数据库模型被改为managed=True(手动或通过上述脚本)时才会出现此问题。如果不修改任何模型,测试数据库创建过程不会报错,但生成的测试数据库中没有任何表。应用中唯一不使用外部数据库、默认已设置managed=True的模型,在创建测试数据库时未引发错误。

以下是错误回溯示例:Students_with_Holds是Coursematch外部数据库中的表,其Django模型在测试时被修改为managed=True。测试本身仅执行assert True,但添加了@pytest.mark.django_db(databases=['Coursematch'])装饰器。

------- ERROR at setup of TestLetterGenerator.test_db_access --------

self = <django.db.backends.utils.CursorWrapper object at 0x7f72edc60730>
sql = 'SELECT [Students_with_Holds].[Person_ID_Number], [Students_with_Holds].[Hold_Type_Code], [Students_with_Holds].[Hold_...h_Holds].[Date_Applied] FROM [Students_with_Holds] ORDER BY [Students_with_Holds].[Person_ID_Number] ASC OFFSET 0 ROWS'
params = ()
ignored_wrapper_args = (False, {'connection': <mssql.base.DatabaseWrapper object at 0x7f72ee2c1e80>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7f72edc60730>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
                # params default might be backend specific.
                return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)

/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py:84: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <mssql.base.CursorWrapper object at 0x7f72edc60b50>
sql = 'SELECT [Students_with_Holds].[Person_ID_Number], [Students_with_Holds].[Hold_Type_Code], [Students_with_Holds].[Hold_...h_Holds].[Date_Applied] FROM [Students_with_Holds] ORDER BY [Students_with_Holds].[Person_ID_Number] ASC OFFSET 0 ROWS'
params = ()

    def execute(self, sql, params=None):
        self.last_sql = sql
        sql = self.format_sql(sql, params)
        params = self.format_params(params)
        self.last_params = params
        try:
>           return self.cursor.execute(sql, params)
E           pyodbc.ProgrammingError: ('42S02', "[42S02] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid object name 'Students_with_Holds'. (208) (SQLExecDirectW)")

/usr/local/lib/python3.9/site-packages/mssql/base.py:621: ProgrammingError

The above exception was the direct cause of the following exception:

request = <SubRequest '_django_db_marker' for <Function test_db_access>>

    @pytest.fixture(autouse=True)
    def _django_db_marker(request) -> None:
        """Implement the django_db marker, internal to pytest-django."""
        marker = request.node.get_closest_marker("django_db")
        if marker:
>           request.getfixturevalue("_django_db_helper")

/usr/local/lib/python3.9/site-packages/pytest_django/plugin.py:465: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.9/site-packages/pytest_django/fixtures.py:122: in django_db_setup
    db_cfg = setup_databases(
/usr/local/lib/python3.9/site-packages/django/test/utils.py:179: in setup_databases
    connection.creation.create_test_db(
/usr/local/lib/python3.9/site-packages/django/db/backends/base/creation.py:90: in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
/usr/local/lib/python3.9/site-packages/django/db/backends/base/creation.py:136: in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
/usr/local/lib/python3.9/site-packages/django/core/serializers/__init__.py:129: in serialize
    s.serialize(queryset, **options)
/usr/local/lib/python3.9/site-packages/django/core/serializers/base.py:90: in serialize
    for count, obj in enumerate(queryset, start=1):
/usr/local/lib/python3.9/site-packages/django/db/backends/base/creation.py:133: in get_objects
    yield from queryset.iterator()
/usr/local/lib/python3.9/site-packages/django/db/models/query.py:353: in _iterator
    yield from self._iterable_class(self, chunked_fetch=use_chunked_fetch, chunk_size=chunk_size)
/usr/local/lib/python3.9/site-packages/django/db/models/query.py:51: in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
/usr/local/lib/python3.9/site-packages/django/db/models/sql/compiler.py:1175: in execute_sql
    cursor.execute(sql, params)
/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py:66: in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py:75: in _execute_with_wrappers
    return executor(sql, params, many, context)
/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py:84: in _execute
    return self.cursor.execute(sql, params)
/usr/local/lib/python3.9/site-packages/django/db/utils.py:90: in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py:84: in _execute
    return self.cursor.execute(sql, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <mssql.base.CursorWrapper object at 0x7f72edc60b50>
sql = 'SELECT [Students_with_Holds].[Person_ID_Number], [Students_with_Holds].[Hold_Type_Code], [Students_with_Holds].[Hold_...h_Holds].[Date_Applied] FROM [Students_with_Holds] ORDER BY [Students_with_Holds].[Person_ID_Number] ASC OFFSET 0 ROWS'
params = ()

    def execute(self, sql, params=None):
        self.last_sql = sql
        sql = self.format_sql(sql, params)
        params = self.format_params(params)
        self.last_params = params
        try:
>           return self.cursor.execute(sql, params)
E           django.db.utils.ProgrammingError: ('42S02', "[42S02] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid object name 'Students_with_Holds'. (208) (SQLExecDirectW)")

/usr/local/lib/python3.9/site-packages/mssql/base.py:621: ProgrammingError

内容的提问来源于stack exchange,提问作者Enderhippo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 18:55:00