Django - OperationalError: (2006, "сервер MySQL ушел" )
В нижней строке: Как вы обновляете соединение 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
Ответы
Ответ 1
с той же проблемой.
Мне нужна идея, как проверить состояние соединения для подключения MySQLdb в django.
я думаю, это может быть достигнуто
try:
cursor.execute(sql)
catch OperationalError:
reconnect
кто-нибудь лучше знает?
UPDATE
мое решение
self.connection.stat()
if self.connection.errno()!=0:
проверить состояние соединения mysqldb, если ошибка воссоздает соединение
UPDATE AGAIN
вам также нужно обслуживать случай, если соединение близко
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
Ответ 2
Идея решения понятна: подключитесь к 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
Ответ 3
Начиная с Django 1.6, вы можете использовать
import django.db
django.db.close_old_connections()
Это в основном то же самое, что и ответ adamsmith, за исключением того, что он обрабатывает несколько баз данных, а также CONN_MAX_AGE
настройку CONN_MAX_AGE
. Django вызывает close_old_connections()
автоматически до и после каждого запроса, поэтому вам, как правило, не нужно беспокоиться об этом, если у вас нет какого-либо долгосрочного кода вне обычного цикла запрос/ответ.
Ответ 4
Основная причина, которая приводит к этому исключению, в основном из-за того, что клиент идеален дольше, чем 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
сохранит старые соединения, если они еще не истекли. Ваши соединения все еще используются повторно в случае высокочастотного запроса.