Python Django在PostgreSQL死亡时未重新连接,是否需要自定义后端?

Python Django在PostgreSQL死亡时未重新连接,是否需要自定义后端?,python,django,postgresql,backend,custom-backend,Python,Django,Postgresql,Backend,Custom Backend,我已经做了一些测试,并且能够确认使用Django与PostgreSQL和PGBouncer时,它不会在失去连接时自动重新连接。老实说,我不确定这是一个bug还是设计的。如果它是一个错误,我会很高兴地报告它,如果不是,我想一些解释为什么和如何绕过它,而不是另一个自定义后端 通过在Django 1.8.4和Django 1.8.6上执行以下操作,我相当轻松地完成了这些测试: >>>Model.objects.all().count() 24 # Restart postgres w

我已经做了一些测试,并且能够确认使用
Django
PostgreSQL
PGBouncer
时,它不会在失去连接时自动重新连接。老实说,我不确定这是一个bug还是设计的。如果它是一个错误,我会很高兴地报告它,如果不是,我想一些解释为什么和如何绕过它,而不是另一个自定义后端

通过在
Django 1.8.4
Django 1.8.6
上执行以下操作,我相当轻松地完成了这些测试:

>>>Model.objects.all().count()
24
# Restart postgres with `sudo service postgres restart`
>>>Model.objects.all().count()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 318, in count
    return self.query.get_count(using=self.db)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 466, in get_count
    number = obj.get_aggregation(using, ['__count'])['__count']
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 447, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 98, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
OperationalError: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
现在来看看代码:

from django.db.backends.postgresql_psycopg2.base import DatabaseError, \
    IntegrityError, DatabaseWrapper as PostgresWrapper

class DatabaseWrapper(PostgresWrapper):
    def _reconnect(self):
        try:
            self.connect()
        except (DatabaseError, OperationalError):
            pass

    def ensure_connection(self):
        """
        Guarantees that a connection to the database is established.
        """
        if self.connection is None:
            with self.wrap_database_errors:
                self._reconnect()
        else:
            try:
                self.connection.cursor().execute('SELECT 1')
            except (DatabaseError, OperationalError):
                self._reconnect()

我想我终于明白了。我不完全确定我的第一种方法有什么问题,但这一种似乎工作得更好

class DatabaseWrapper(PostgresWrapper):
    def _cursor(self):
        if self.connection is not None:
            if not self.is_usable():
                self.connection.close()
                self.connection = None
        return super(DatabaseWrapper, self)._cursor()
编辑:最终公开了这项工作。我不确定它是否100%需要,但在服务器上重新启动Postgres服务后,它工作正常。您可以在pypi上找到它,它的名称是django postgreconnect,也可以在GitHub上找到它

class DatabaseWrapper(PostgresWrapper):
    def _cursor(self):
        if self.connection is not None:
            if not self.is_usable():
                self.connection.close()
                self.connection = None
        return super(DatabaseWrapper, self)._cursor()