Python的:MySQL的:处理超时(Python: MySQL: Handling timeou

2019-07-04 03:22发布

我使用Python和MySQL,并有查询之间的长期滞后。 其结果是,我得到一个“MySQL连接已经走了”的错误,那就是WAIT_TIMEOUT超出。

这已经讨论例如,在处理“MySQL已经走了”正常

但是这并没有具体回答我的查询。

所以我的方法来处理这个 - 我已经包裹我所有的SQL作为方法执行语句 -

  def __execute_sql(self,sql,cursor):
    try:
        cursor.execute(sql)

    except MySQLdb.OperationalError, e:            
        if e[0] == 2006:
            self.logger.do_logging('info','DB', "%s : Restarting db" %(e))
            self.start_database()

我在调用该查询的代码的几个地方。 关键是,我也有几个游标,因此该方法调用看起来喜欢 -

self.__execute_sql(sql,self.cursor_a)
self.__execute_sql(sql,self.cursor_b)

等等

我需要一种方法分贝启动后优雅地重新执行查询。 if语句我可以换的电话在,并重新执行,因此会

def __execute_sql(self,sql,cursor):
    try:
        cursor.execute(sql)
        return 1
except MySQLdb.OperationalError, e:            
    if e[0] == 2006:
        self.logger.do_logging('info','DB', "%s : Restarting db" %(e))
        self.start_database()
        return 0

然后

if (self.__execute_sql(sql,self.cursor_a) == 0):
   self.__execute_sql(sql,self.cursor_a)

但是,这是笨重。 有一个更好的方法吗? 谢谢!!!

Answer 1:

我试图Crasched的做法,这让我到一个新的OperationalError:

OperationalError: (2013, 'Lost connection to MySQL server during query')

我最终的解决办法是先试平,如果另一OperationalError提高后,重新连接并重新创建光标,新的连接,就像这样:

try:
    self.connection.ping(True)
except MySQLdb.OperationalError:
    self.connection = MySQLdb.connect(
        self.db_host,
        self.db_user,
        self.db_passwd,
        self.db_dbase,
        self.db_port)
    # reconnect your cursor as you did in __init__ or wherever    
    self.cursor = self.connection(
        MySQLdb.cursors.DictCursor)

回到工作!

Python 2.7版中,MySQL 41年5月5日



Answer 2:

我有同样的问题,并希望包裹例外捕捉到它,而是我用以下解决它。 之前调用执行,通话
self.con.ping(TRUE)

http://www.neotitans.com/resources/python/mysql-python-connection-error-2006.html http://mysql-python.sourceforge.net/MySQLdb.html

我再也找不到我发现了这一点,从原来的源材料,但这种立即解决了这个问题。



Answer 3:

我也陷入了神秘的“MySQL服务器消失”的错误,这里是我的解决方案。

该解决方案将让你通过MySQL的错误重试,处理几乎任何类型的查询,在查询中包含STR或在一个单独的元组查询变量,并收集并返回你前进的道路上遇到的成功和错误信息:

def execute_query(query_str, values=None):
  # defaults
  num_affected_rows = 0
  result_rows = None
  success = False
  message = "Error executing query: {}".format(query_str)
  # run the query
  try:
    mysql_conn = get_existing_mysql_connection()
    cur = mysql_conn.cursor()
    if values == None or len(values) < 1:
      num_affected_rows = cur.execute(query_str)
    else:
      num_affected_rows = cur.execute(query_str, values)
    result_rows = cur.fetchall() # only relevant to select, but safe to run with others
    cur.close()
    mysql_conn.commit()
    success = True
    message = "Mysql success for query: {}".format(query_str)
  except BaseException as e:
    message = "Mysql error: {}; for query: {}".format(repr(e), query_str)
  return (success, num_affected_rows, result_rows, message)


def execute_query_with_retry(query_str, values=None, num_tries=3, message=""):
  # defaults
  success = False
  num_affected_rows = 0
  result_rows = None
  this_message = "Error executing query: {}".format(query_str)
  # should we still try?
  if num_tries < 1:
    this_message = "Ran out of tries for query: {}".format(query_str)
    return (False, 0, None, message + '; ' + this_message)
  num_tries_after_this = num_tries - 1
  # try to execute query
  try:
    (success, num_affected_rows, result_rows, this_message) = execute_query(query_str, values)
  except BaseException as e:
    success = False
  # handle success or failure
  if success == True:
    return (True, num_affected_rows, result_rows, message + '; ' + this_message)
  else:
    open_new_mysql_connection() # reconnect using password etc.
    return(execute_query_with_retry(query_str, values=values, num_tries=num_tries_after_this, message=(message + '; ' + this_message)))


文章来源: Python: MySQL: Handling timeouts