Подтвердить что ты не робот

Как включить автоматическое повторное подключение клиента MySQL с MySQLdb?

Я натолкнулся на PHP-способ сделать трюк:

my_bool reconnect = 1;
mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);

но не повезло с MySQLdb (python-mysql).

Кто-нибудь, пожалуйста, дайте подсказку? Спасибо.

4b9b3361

Ответ 1

Я решил эту проблему, создав функцию, которая обертывает метод 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

Ответ 2

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

Я решил проблему с оператором 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

Ответ 3

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

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

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

python-mysqldb (1.2.2-7) нестабилен; Актуальность = низкий

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

[Bernd Zeimetz] * debian/patches/02_reconnect.dpatch:   - Отбрасывание патча:     Комментарий в Storm, который объясняет проблему:

    # 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 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.

Ответ 4

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

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() 

Ответ 5

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

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

Ответ 6

Вы также ставите, что он сам работает с потерянными соединениями с кодом.

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

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