# Custom DB backend postgresql_psycopg2 based # implements persistent database connection using thread local storage from threading import local from django.db.backends.postgresql_psycopg2.base import DatabaseError, \ DatabaseWrapper as BaseDatabaseWrapper, IntegrityError from psycopg2 import OperationalError threadlocal = local() class DatabaseWrapper(BaseDatabaseWrapper): def is_alive(self, connection): try: # Check if connection is alive connection.cursor().execute('SELECT 1') except (DatabaseError, OperationalError): return False else: return True @property def local_key(self): return '{}_{}'.format(self.settings_dict.get('NAME', 'db'), 'connection') @property def local_connection(self): return getattr(threadlocal, self.local_key, None) @local_connection.setter def local_connection(self, connection): setattr(threadlocal, self.local_key, connection) def _cursor(self, *args, **kwargs): if self.local_connection is not None and self.connection is None: if self.is_alive(self.local_connection): self.connection = self.local_connection else: self.local_connection = None elif self.connection is not None: if self.is_alive(self.connection): self.local_connection = self.connection else: self.connection.close() self.connection = None self.local_connection = None cursor = super(DatabaseWrapper, self)._cursor(*args, **kwargs) if self.local_connection is None and self.connection is not None: self.local_connection = self.connection return cursor def close(self): if self.connection is not None: self.connection.commit() self.connection = None