django.db.utils.InterfaceError: Verbindungsfehler beim Aktualisieren auf Django 3.0 bereits geschlossen

9

Ich aktualisiere ein mittelgroßes Projekt auf Django 3.0 und stoße bei meinen Tests auf mehrere Fehler, nachdem ich lediglich die Django-Version von 2.3 gestoßen habe.

Die gesamte Testsuite läuft seit Jahren ordnungsgemäß und ich konnte keine relevante Änderung im Änderungsprotokoll finden, die auf die Ursache dieses Problems hinweisen könnte. Anscheinend löst ein einzelner Testfehler aus, dass jeder verbleibende Test in derselben TestCase-Klasse mit der folgenden Ausnahme fehlschlägt:

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

Ich habe keine Ahnung, was hier vor sich gehen könnte.

Federico B.
quelle
2
Bitte zeigen Sie eine vollständige Stapelverfolgung und einen relevanten Codeteil
Max Malysh
Ich habe das Problem mit einem längeren Stack-Trace aktualisiert. Leider kann ich es nicht einem bestimmten Codeteil zuordnen.
Federico B.
1
Nein, jeder Test, den Fehler connection already closedauslösen, wird für alle verbleibenden Tests in der TestCase-Klasse ausgelöst.
Federico B.
1
Eine gute Möglichkeit, diese Art von Problem zu beheben, besteht darin, den Datenbankverkehr mit tcpdump zu erfassen und mit Wireshark zu überprüfen . Es scheint, dass Postgres die Verbindung schließt, sodass die Abfragen möglicherweise zeigen, warum.
Ionut Ticus
2
Ich habe festgestellt, dass wenn Sie TransactionTestCase für jeden Test anstelle von TestCase verwenden, dies irgendwie verhindert. Ich verstehe nicht wie oder warum.
Jaredkwright

Antworten:

2

Ich bin auch darauf gestoßen. Es scheint ein Fehler zu sein pytest-django. Hier ist das relevante Problem . Es gibt eine offene PR , um das Problem zu beheben. Wenn die Unannehmlichkeiten groß genug sind, können Sie den Zweig in dieser PR verwenden oder Ihre Abhängigkeiten an eine frühere Version anheften.

schillingt
quelle
1

Nur eine Vorwärtsnotiz, es ist nahezu unmöglich, mehr Informationen bereitzustellen, als bereits im Stacktrace enthalten sind. Sie können jedoch Folgendes untersuchen:

  • Überprüfen Sie, wann die Verbindung geschlossen wird und mit welchem ​​Test (führen Sie sie beispielsweise einzeln per Skript aus).
  • Überprüfen Sie bei fehlgeschlagenen Tests den Code auf veraltete Teile von Django (suchen Sie nach Dingen, die zwischen 2.3 und 3.0 entfernt / veraltet wurden).
  • Führen Sie einen Linter aus, um festzustellen, ob jemand eine private Variable innerhalb des Django-Frameworks als Problemumgehung geändert hat.
  • Überprüfen Sie die Transaktionen von Postgres.

Wenn Sie dann wissen, welcher Teil des Codes den Fehler aufweist, können Sie ihn eingrenzen, indem Sie kleinere Fehlertests erstellen.

Höhlenmensch
quelle
1

Wir hatten das gleiche Problem und ein Upgrade von Django 3.0.2 auf Django-3.0.4 hat es behoben. In diesen beiden Versionen gibt es mehrere DB-bezogene Korrekturen, aber ich weiß nicht, welche unser Problem gelöst hat.

bimmlerd
quelle
0

Ich hatte das gleiche Problem mit Pytest.

Ein Downgrade von 5.4.1 auf 5.3.5 hat das Problem behoben.

P4rk
quelle
0

All diese Probleme treten aufgrund der Inkompatibilität der anderen Pakete mit django 3.0 auf, als ich auf diesen Fehler stieß. Ich habe meine Datei request.txt manuell aktualisiert und dann alle Anforderungen mithilfe von pip in derselben Umgebung installiert.

raven404
quelle