I’m encountering a "connection already closed" error in my Django application that uses PostgreSQL as the database backend. Despite trying various solutions, I can’t seem to resolve this issue.
Background Information:
Django
4.2.13psycopg2
2.9.9
Problem Statement
I have a Django application that intermittently throws a "connection already closed" error when trying to interact with the PostgreSQL database. This issue often arises under the following circumstances:
Running background task for inserting data into db in every 30 seconds
errors: File "djangoutilsasyncio.py", line 26, in innerreturn func(*args, **kwargs)
File "djangodbbackendsbasebase.py", line 330, in cursorreturn self._cursor()
File "djangodbbackendsbasebase.py", line 308, in _cursorreturn self._prepare_cursor(self.create_cursor(name))
File "djangodbutils.py", line 91, in exitraise dj_exc_value.with_traceback(traceback) from exc_value
File "djangodbbackendsbasebase.py", line 308, in _cursorreturn self._prepare_cursor(self.create_cursor(name))
File "djangoutilsasyncio.py", line 26, in innerreturn func(*args, **kwargs)
File "djangodbbackendspostgresqlbase.py", line 330, in create_cursorcursor =
self.connection.cursor()django.db.utils.InterfaceError: connection already closed
What I’ve Tried
- Ensured that the database connection parameters are correct.
- Checked for any long-running queries that might be causing timeouts.
- Adjusted Django’s database connection settings such as
CONN_MAX_AGE
andCONN_HEALTH_CHECKS
. - Increased the connection timeout settings in PostgreSQL.
Despite these attempts, the issue persists.
2
Answers
CONN_HEALTH_CHECKS
only works in a (HTTP) request context. It doesn’t do anything when used in a background task:This is a known issue.
You should be doing a similar check manually in your loop. We don’t see your actual code, but it will be something similar to the following:
If the issue is related to restarting the PostgreSQL service (reboot, apt update, etc.), you can define a dependency in your Django service file so that the Django service restarts when the PostgreSQL service is restarted. For this, you can use the BindsTo and After directives: