web-dev-qa-db-ja.com

django.db.utils.InterfaceError:Django 3.0に更新するとき、接続はすでに閉じられています

中規模のプロジェクトをDjango 3.0に更新しています。2.3からDjangoバージョンをバンプする以外に何もしないと、テストでいくつかのエラーが発生します。

テストスイート全体が何年もの間正しく実行されており、この問題の原因を示す可能性のある変更ログ内の関連する変更を見つけることができませんでした。どうやら、1つのテストが失敗すると、同じTestCaseクラスの残りのすべてのテストが失敗し、次の例外が発生します。

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

私はここで何が起こっているのかについての考えがありません。

6
Federico B.

私もこれに遭遇しました。 pytest-Djangoのバグのようです。 関連する問題 を次に示します。それを解決するために open PR があります。それが十分に不便な場合は、そのPRのブランチを使用するか、依存関係を以前のバージョンに固定できます。

1
schillingt

ただ前向きな注意として、スタックトレースにすでにあるよりも多くの情報を提供することはほぼ不可能です。ただし、以下を調査できます。

  • 接続が閉じられるタイミングとテスト(たとえば、スクリプトを使用して個別に実行)を確認します。
  • 失敗したテストについては、Django(2.3と3.0の間で削除/非推奨になったものを検索))の非推奨部分のコードを確認してください。
  • リンターを実行して、Djangoフレームワーク内のプライベート変数が回避策として変更されたかどうかを確認します。
  • Postgresのトランザクションを確認します。

次に、コードのどの部分にエラーがあるかを確認したら、失敗するテストを小さくして、コードを絞り込みます。

0
Caveman

同じ問題が発生し、Django 3.0.2からDjango-3.0.4にアップグレードすると解決しました。これらの2つのバージョンにはDB関連の修正がいくつかありますが、 1つは私たちの問題を解決しました。

0
bimmlerd

Pytestを使用して同じ問題が発生しました。

5.4.1から5.3.5にダウングレードして修正しました。

0
P4rk