Python django.db.utils.InterfaceError:更新到django 3.0时,连接已关闭失败
我正在将一个中等规模的项目更新到Django3.0,在我的测试中遇到了几个错误,因为我只是将Django版本从2.3升级到了2.3 整个测试套件已经正确运行了多年,我在变更日志中找不到任何相关的变更,这些变更可能会指向此问题的原因。显然,单个测试失败会触发同一TestCase类中的所有剩余测试失败,出现以下异常:Python django.db.utils.InterfaceError:更新到django 3.0时,连接已关闭失败,python,django,psycopg2,Python,Django,Psycopg2,我正在将一个中等规模的项目更新到Django3.0,在我的测试中遇到了几个错误,因为我只是将Django版本从2.3升级到了2.3 整个测试套件已经正确运行了多年,我在变更日志中找不到任何相关的变更,这些变更可能会指向此问题的原因。显然,单个测试失败会触发同一TestCase类中的所有剩余测试失败,出现以下异常: Traceback (most recent call last): File "/Users/federicobond/code/forks/core/env/lib/pytho
Traceback (most recent call last):
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/base/base.py", line 238, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/utils/asyncio.py", line 24, in inner
return func(*args, **kwargs)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 231, in create_cursor
cursor = self.connection.cursor()
psycopg2.InterfaceError: connection already closed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/federicobond/code/forks/core/apps/participants/tests/test_views.py", line 40, in setUp
self.client.force_login(self.user)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/test/client.py", line 602, in force_login
self._login(user, backend)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/test/client.py", line 611, in _login
if self.session:
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/test/client.py", line 461, in session
session.save()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/contrib/sessions/backends/db.py", line 81, in save
return self.create()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/contrib/sessions/backends/db.py", line 51, in create
self._session_key = self._get_new_session_key()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/contrib/sessions/backends/base.py", line 162, in _get_new_session_key
if not self.exists(session_key):
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/contrib/sessions/backends/db.py", line 47, in exists
return self.model.objects.filter(session_key=session_key).exists()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/models/query.py", line 777, in exists
return self.query.has_results(using=self.db)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/models/sql/query.py", line 534, in has_results
return compiler.has_results()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1107, in has_results
return bool(self.execute_sql(SINGLE))
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1135, in execute_sql
cursor = self.connection.cursor()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/utils/asyncio.py", line 24, in inner
return func(*args, **kwargs)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/base/base.py", line 260, in cursor
return self._cursor()
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/base/base.py", line 238, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/base/base.py", line 238, in _cursor
return self._prepare_cursor(self.create_cursor(name))
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/utils/asyncio.py", line 24, in inner
return func(*args, **kwargs)
File "/Users/federicobond/code/forks/core/env/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 231, in create_cursor
cursor = self.connection.cursor()
django.db.utils.InterfaceError: connection already closed
我不知道这里会发生什么。只是一个预告,几乎不可能提供比stacktrace中更多的信息。但是,您可以调查:
- 检查连接何时关闭以及在哪个测试之前关闭(例如,通过脚本单独运行它们)李>
- 对于失败的测试,请检查代码中Django的不推荐部分(搜索在2.3和3.0之间删除/不推荐的内容)
- 运行linter以查看是否有人在Django框架内更改了私有变量作为解决方法
- 检查postgres的交易记录
然后,一旦您确定了错误出现在代码的哪一部分,就可以通过创建较小的失败测试来缩小错误范围。我也遇到了这个问题。这似乎是pytest django中的一个bug。这是我的建议。有一个解决方案。如果这是一个很大的不便,您可以使用该PR中的分支,或者将依赖项绑定到早期版本。我们遇到了相同的问题,从Django 3.0.2升级到Django-3.0.4解决了它。在这两个版本中有几个与DB相关的修复程序,但我不知道是哪一个解决了我们的问题。我在使用pytest时遇到了同样的问题
从5.4.1降级到5.3.5修复了它。所有这些问题都是由于其他包与django 3.0不兼容而出现的
当我遇到此错误时,我手动更新了requirement.txt文件,然后在同一环境中使用pip安装了所有需求。请显示完整的堆栈跟踪和相关的代码部分,我用更长的堆栈跟踪更新了问题。不幸的是,我无法将其精确定位到特定的代码部分。不,对于TestCase类中的所有剩余测试,错误触发的每个测试都已关闭连接。。调试此类问题的一个好方法是使用tcpdump之类的工具捕获数据库流量,并使用Wireshark进行检查;Postgres似乎正在关闭连接,因此查询可能会揭示原因。我注意到,如果对每个测试使用TransactionTestCase而不是TestCase,它会以某种方式阻止这种情况发生。我不明白怎么做或者为什么。