psycopg2断开与服务器的连接

14 投票
4 回答
17945 浏览
提问于 2025-04-15 15:05

我最近一直在解决这个问题。我设置了一台全新的电脑,安装了最新的PostgreSQL和其他所有需要的依赖。基本上,我在随机的时间会遇到数据库断开连接的情况。我可以发送相同的请求,有时候成功,有时候失败,看起来非常不稳定。在查看PostgreSQL的日志时,发现根本没有连接记录。按理说,如果从未连接成功,我应该在建立连接和获取游标的时候就会遇到问题,但实际上我是在稍后尝试使用连接时才遇到问题。根据下面的错误追踪信息,我本应该在pg日志中看到连接成功的记录,然后因为某种原因断开连接。但我没有看到,所以我在想这个不匹配是否有什么线索。

Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/core/handlers/wsgi.py", line 242, in __call__
    response = self.get_response(request)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/core/handlers/base.py", line 73, in get_response
    response = middleware_method(request)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/middleware/locale.py", line 16, in process_request
    language = translation.get_language_from_request(request)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/utils/translation/__init__.py", line 97, in get_language_from_request
    return real_get_language_from_request(request)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/utils/translation/trans_real.py", line 349, in get_language_from_request
    lang_code = request.session.get('django_language', None)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/contrib/sessions/backends/base.py", line 63, in get
    return self._session.get(key, default)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/contrib/sessions/backends/base.py", line 172, in _get_session
    self._session_cache = self.load()
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/contrib/sessions/backends/db.py", line 16, in load
    expire_date__gt=datetime.datetime.now()
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/manager.py", line 120, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/query.py", line 300, in get
    num = len(clone)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/query.py", line 81, in __len__
    self._result_cache = list(self.iterator())
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/query.py", line 238, in iterator
    for row in self.query.results_iter():
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/sql/query.py", line 287, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/models/sql/query.py", line 2369, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/Django-1.1-py2.6.egg/django/db/backends/util.py", line 19, 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.

4 个回答

2

你有没有使用fork()来创建子进程(比如使用预先创建的FastCGI或类似的东西)?这可能是导致在父进程中建立的连接在子进程中无法使用的原因。如果你使用的是预先创建的方法,可以很简单地切换到线程来看看问题是否解决了。我在这种情况下也遇到过完全相同的错误。

3

虽然这个问题很老,但我找到的最佳解决方案在这个回答里。只需要按照以下步骤操作:

from django import db

在调用fork或者使用多进程之前,先执行:

db.connections.close_all()
5

这个问题跟这里提到的那个问题非常相似:

Django + FastCGI - 随机出现 OperationalError

我想,如果有人最终找到了答案,这两个问题的答案应该是一样的。这个问题困扰了我大约一个月,我完全不知道是什么原因导致的。

撰写回答