使用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
相关产品推荐
相关产品推荐

