Django - OperationalError :( 2006,'MySQL服务器已经消失')

时间:2011-10-20 11:30:56

标签: mysql django

第一个底线:如何刷新django中的MySQL连接?

发现MySQL server has gone away错误后,我发现MySQL documentation和其他来源(here)建议增加wait_timeout MySQL参数。对我来说,这似乎是一种解决方法而不是解决方案。我宁愿保持合理的wait_timeout并刷新代码中的连接。

错误:

  File "C:\my_proj\db_conduit.py", line 147, in load_some_model
    SomeModel.objects.update()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\models\manager.py", line 177, in update
    return self.get_query_set().update(*args, **kwargs)
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\models\query.py", line 469, in update
    transaction.commit(using=self.db)
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\transaction.py", line 142, in commit
    connection.commit()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\backends\__init__.py", line 201, in commit
    self._commit()
  File "C:\Python26\lib\site-packages\django-1.3-py2.6.egg\django\db\backends\__init__.py", line 46, in _commit
    return self.connection.commit()
OperationalError: (2006, 'MySQL server has gone away')

设置:Django 1.3.0,MySQL 5.5.14,innodb 1.1.8,Python 2.6.6,Win7 64bit

5 个答案:

答案 0 :(得分:6)

有同样的问题。 我需要知道如何在django中检查MySQLdb连接的连接状态。 我想这可以通过

来实现
try:
    cursor.execute(sql)
catch OperationalError:
    reconnect

有人有更好的主意吗?

<强>更新

我的决定

self.connection.stat()
if self.connection.errno()!=0:

如果错误重新创建连接

,请检查mysqldb连接的状态

再次更新

如果连接关闭,您还需要提供服务

if self.connection.open:
    self.connection.stat()

刷新连接只是重新创建它

    db_settings = settings.DATABASES['mysql_db']
    try:
        self.connection = MySQLdb.connect(host=db_settings['HOST'],port=int(db_settings['PORT']),db=db_settings['NAME'],user=db_settings['USER'],passwd=db_settings['PASSWORD'])
    except MySQLdb.OperationalError, e:
        self.connection = None

答案 1 :(得分:6)

解决方案的想法很明确:如果当前连接中断,请重新连接到mysql。

请检查一下:

def make_sure_mysql_usable():
    from django.db import connection, connections
    # mysql is lazily connected to in django.
    # connection.connection is None means
    # you have not connected to mysql before
    if connection.connection and not connection.is_usable():
        # destroy the default mysql connection
        # after this line, when you use ORM methods
        # django will reconnect to the default mysql
        del connections._connections.default

答案 2 :(得分:0)

从Django 1.6开始,您可以使用

import django.db

django.db.close_old_connections()

这与adamsmith的回答基本相同,不同之处在于它处理多个数据库并支持CONN_MAX_AGE设置。 Django在每个请求之前和之后都会自动调用close_old_connections(),因此,除非您在正常请求/响应周期之外有一些长时间运行的代码,否则通常不必担心。

答案 3 :(得分:0)

导致此异常的主要原因主要是由于客户端理想时间比mysql服务器上的wait_timeout长。

为了防止此类错误,django支持名为CONN_MAX_AGE的选项,如果理想的旧连接太长,则允许django重新创建新连接。 因此,您应确保CONN_MAX_AGE的值小于wait_timout的值。

重要的一点是,带有django的{​​{1}}通过调用wsgi来处理检查CONN_MAX_AGE的每个请求。因此,您主要不需要关心这一点。但是,如果您在标准的单独应用程序中使用close_old_connections,则没有触发器可以运行该功能。因此,您必须手动调用它。因此,请在您的代码库中调用django

注意:close_old_connections将保留旧的连接(如果尚未过期)。在高频查询的情况下,您的连接仍然可以重用。

答案 4 :(得分:0)

这种方式也可以关闭空闲连接,让事情变得更好。

因此,在长时间后需要进行查询之前,运行以下几行即可:

from django.db import close_old_connections

# To prevent the error if possible.
close_old_connections()
# Then the following sentence should be always ok.
YourModel.objects.all()