2008-10-16 5 views

ответ

8

Если вы используете ubuntu Linux, в пакет python-mysql добавлен патч, который добавил возможность установки той же опции MYSQL_OPT_RECONNECT (см. here). Однако я не пробовал.

К сожалению, патч был удален из-за конфликта с автосоединением и трансациями (описано here).

Комментариев от этой страницы говорят: 1.2.2-7 Опубликованы в бесстрашном-релизе на 2008-06-19

питона-MySQLdb (1.2.2-7) неустойчив; Актуальность = низкий

[Сандро Тоси] * Debian/управления - элементы списка строк в описании начинается с 2 пространства, чтобы избежать переформатирование на веб-страницах (Закрывает: # 480341)

[Бернд Zeimetz] * Debian/патчи/02_reconnect.dpatch: - капают патч: Комментарий в шторм, который объясняет проблему:

# Here is another sad story about bad transactional behavior. MySQL 
    # offers a feature to automatically reconnect dropped connections. 
    # What sounds like a dream, is actually a nightmare for anyone who 
    # is dealing with transactions. When a reconnection happens, the 
    # currently running transaction is transparently rolled back, and 
    # everything that was being done is lost, without notice. Not only 
    # that, but the connection may be put back in AUTOCOMMIT mode, even 
    # when that's not the default MySQLdb behavior. The MySQL developers 
    # quickly understood that this is a terrible idea, and removed the 
    # behavior in MySQL 5.0.3. Unfortunately, Debian and Ubuntu still 
    # have a patch right now which *reenables* that behavior by default 
    # even past version 5.0.3. 
+0

Я думаю, все, что клиент делает, потерянное соединение может указывать на потерю того, транзакция (циклическая мощность сервера) или потеря подключения. Поэтому я согласен с тем, что простое повторное подключение может скрывать потерю данных от ожидания пользователя клиента mysql. – 2011-07-06 17:05:27

-3

Вы другие ставки, чтобы работать вокруг разрыва соединения себя с кодом.

Один из способов сделать это было бы следующее:

import MySQLdb 

class DB: 
    conn = None 

    def connect(self): 
     self.conn = MySQLdb.connect() 

    def cursor(self): 
     try: 
      return self.conn.cursor() 
     except (AttributeError, MySQLdb.OperationalError): 
      self.connect() 
      return self.conn.cursor() 

db = DB() 
cur = db.cursor() 
# wait a long time for the Mysql connection to timeout 
cur = db.cursor() 
# still works 
+4

На самом деле этот не работает. Создание курсора не создает связи с БД и поэтому не вызывает исключение OperationError. – Boaz 2011-09-20 15:09:24

1

У меня была аналогичная проблема с MySQL и Python, и решения, которые работали для меня было обновить MySQL до 5.0.27 (на Fedora Core 6, ваша система может работать отлично с другой версией).

Я пробовал много других вещей, включая исправление библиотек Python, но обновление базы данных было намного проще и (я думаю) лучшим решением.

65

Я решил эту проблему, создав функцию, которая обертывает метод cursor.execute(), поскольку это то, что выбрасывает исключение MySQLdb.OperationalError. Другой пример выше означает, что это метод conn.cursor(), который генерирует это исключение.

import MySQLdb 

class DB: 
    conn = None 

    def connect(self): 
    self.conn = MySQLdb.connect() 

    def query(self, sql): 
    try: 
     cursor = self.conn.cursor() 
     cursor.execute(sql) 
    except (AttributeError, MySQLdb.OperationalError): 
     self.connect() 
     cursor = self.conn.cursor() 
     cursor.execute(sql) 
    return cursor 

db = DB() 
sql = "SELECT * FROM foo" 
cur = db.query(sql) 
# wait a long time for the Mysql connection to timeout 
cur = db.query(sql) 
# still works 
+0

хорошо ... хороший ответ !! – 2013-01-17 05:53:56

+1

@ garret-heaton - зачем подключаться к AttributeError? Это также бросается, когда соединение становится устаревшим? – aaa90210 2014-07-14 00:14:23

3

Вы можете отделить фиксацию и закрыть соединение ... это не мило, но это так.

class SqlManager(object): 
""" 
Class that handle the database operation 
""" 
def __init__(self,server, database, username, pswd): 

     self.server = server 
     self.dataBase = database 
     self.userID = username 
     self.password = pswd 

def Close_Transation(self): 
     """ 
     Commit the SQL Query 
     """ 
     try: 
     self.conn.commit() 
     except Sql.Error, e: 
     print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1]) 

def Close_db(self): 
    try: 
     self.conn.close() 
    except Sql.Error, e: 
     print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1]) 

def __del__(self): 
    print "close connection with database.." 
    self.conn.close() 
12

У меня были проблемы с предлагаемым решением, потому что оно не было исключением. Я не знаю, почему.

Я решил проблему с ping(True) заявление, которое я считаю аккуратнее:

import MySQLdb 
con=MySQLdb.Connect() 
con.ping(True) 
cur=con.cursor() 

Понял здесь: http://www.neotitans.com/resources/python/mysql-python-connection-error-2006.html

Смежные вопросы