【问题标题】:How can I force django to restart a database connection from the shell?如何强制 django 从 shell 重新启动数据库连接?
【发布时间】:2018-01-18 20:21:48
【问题描述】:

我在 Digital Ocean 服务器上有一个 django 项目。在我的本地机器上,我通过 ssh 连接到数据库:

ssh -L 63333:localhost:5432 me@my.server

并将我的本地 settings.py 更改为:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': 63333
    }
}

在我本地机器上的 Jupyter QtConsole 上,我按照以下步骤进行设置:

import os
import django
os.chdir('/path/to/my/project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'my_project.settings'
django.setup()

在我的 ssh 连接因某种原因中断之前,一切正常。首先我得到这个错误(在查询数据库的一行上,比如my_model.objects.first()):

DatabaseErrorTraceback (most recent call last)
/home/ayhan/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)
     84             else:
---> 85                 return self.cursor.execute(sql, params)
     86 

DatabaseError: server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.

当我通过 ssh 重新连接时,我不断收到以下错误:

InterfaceErrorTraceback (most recent call last)
/home/ayhan/anaconda3/lib/python3.6/site-packages/django/db/backends/base/base.py in _cursor(self, name)
    233         with self.wrap_database_errors:
--> 234             return self._prepare_cursor(self.create_cursor(name))
    235 

/home/ayhan/anaconda3/lib/python3.6/site-packages/django/db/backends/postgresql/base.py in create_cursor(self, name)
    211         else:
--> 212             cursor = self.connection.cursor()
    213         cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None

InterfaceError: connection already closed

只有当我重新启动 IPython 内核时,该错误才会消失。我尝试为设置执行相同的步骤。我也尝试了from importlib import reload; reload(django),然后再次进行设置,但无论如何都会出现相同的错误。

当我不想在内存中丢失变量时,有时会发生这种情况,因此我想避免重新启动内核。有没有办法在没有它的情况下重新创建数据库连接?我正在使用 Python 3.6 和 django 2.0.0。

【问题讨论】:

    标签: python django


    【解决方案1】:

    你可以使用类似下面的东西

    from django.db import connections
    conn = connections['default']
    conn.connect()
    

    from django.db import connection
    connection.connect()
    

    【讨论】:

      【解决方案2】:
      from django.db import connections, connection
      for conn in connections.all():
          conn.close_if_unusable_or_obsolete()
      

      然后调用 connection.cursor 将获得一个新的连接, django源码:

      def _cursor(self, name=None):
          self.ensure_connection()
          with self.wrap_database_errors:
              return self._prepare_cursor(self.create_cursor(name))
      

      【讨论】:

      • conn.close_if_unusable_or_obsolete() --- 这个代码部分对我非常有用。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      相关资源
      最近更新 更多