Django - OperationalError: (2006, «сервер MySQL ушел») - PullRequest
12 голосов
/ 20 октября 2011

В нижней строке: Как обновить соединение MySQL в django?

После ошибки MySQL server has gone away я обнаружил, что документация MySQL и другие источники ( здесь ) предлагают увеличить параметр 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

Ответы [ 4 ]

6 голосов
/ 20 августа 2014

Идея решения ясна: переподключиться к 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
6 голосов
/ 28 октября 2011

с той же проблемой.Мне нужна идея, как проверить состояние соединения для соединения MySQLdb в Django.я думаю, что это может быть достигнуто с помощью

try:
    cursor.execute(sql)
catch OperationalError:
    reconnect

Кто-нибудь есть идея лучше?

ОБНОВЛЕНИЕ

мое решение

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

проверка состояния соединения mysqldb, если ошибка воссоздает соединение* обновить соединение просто воссоздает его

    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
0 голосов
/ 22 июня 2019

Основная причина, которая приводит к этому исключению, главным образом из-за идеального клиента, длиннее wait_timeout на сервере MySQL.

Для предотвращения такого рода ошибок django поддерживает опцию с именем CONN_MAX_AGE, которая позволяет django воссоздавать новое соединение, если старые соединения слишком идеальны.Поэтому вы должны убедиться, что значение CONN_MAX_AGE меньше значения wait_timout.

Одна важная вещь заключается в том, что django с wsgi обрабатывает CONN_MAX_AGE проверку каждого запроса, вызывая close_old_connections.Так что в основном вам не нужно заботиться об этом.Однако, если вы используете django только в стандартном приложении, триггер для запуска этой функции отсутствует.Таким образом, вы должны вызвать его вручную.Поэтому позвольте close_old_connections в вашей кодовой базе.

Примечание: close_old_connections сохранит старые соединения, если они еще не истекли.Ваши соединения все еще используются повторно в случае высокочастотного запроса.

0 голосов
/ 04 сентября 2018

Начиная с Django 1.6, вы можете использовать

import django.db

django.db.close_old_connections()

Это в основном то же самое, что и ответ adamsmith, за исключением того, что он обрабатывает несколько баз данных, а также учитывает настройку CONN_MAX_AGE.Django вызывает close_old_connections() автоматически до и после каждого запроса, поэтому вам, как правило, не нужно беспокоиться об этом, если у вас нет какого-либо долгосрочного кода вне обычного цикла запрос / ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...