Python:MySQL:处理超时

Python:MySQL:处理超时,python,mysql,timeout,Python,Mysql,Timeout,我使用的是Python和mySQL,查询之间有很长的延迟。结果,我得到一个“MySQL连接已消失”错误,即超过等待超时 这一点已经讨论过,例如在 但这并没有具体回答我的问题 所以我的处理方法是- 我将所有sql execute语句包装在一个方法中,如下所示- def __execute_sql(self,sql,cursor): try: cursor.execute(sql) except MySQLdb.OperationalError, e:

我使用的是Python和mySQL,查询之间有很长的延迟。结果,我得到一个“MySQL连接已消失”错误,即超过等待超时

这一点已经讨论过,例如在

但这并没有具体回答我的问题

所以我的处理方法是- 我将所有sql execute语句包装在一个方法中,如下所示-

  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)
但这太笨重了。有更好的方法吗?
谢谢

我遇到了同样的问题,希望包装异常以捕获它,但我使用以下方法解决了它。 调用execute之前,请调用
自我欺骗(真实)


我再也找不到我从中找到的原始资料,但这立即解决了问题。

我尝试了Crasched的方法,这让我遇到了一个新的错误:

OperationalError:(2013,“查询期间与MySQL服务器的连接中断”)

我的最终解决方案是首先尝试ping,如果出现另一个操作错误,则重新连接并使用新连接重新创建光标,如下所示:

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 5.5.41

我遇到了神秘化“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)))
def execute\u query(query\u str,value=None):
#默认值
受影响的行数=0
结果_行=无
成功=错误
message=“执行查询时出错:{}”。格式(query\u str)
#运行查询
尝试:
mysql\u conn=get\u existing\u mysql\u connection()
cur=mysql\u conn.cursor()
如果值==无或len(值)<1:
num\u infected\u rows=cur.execute(查询\u str)
其他:
num\u infected\u rows=cur.execute(查询\u str,值)
result_rows=cur.fetchall()#仅与选择相关,但可以安全地与其他人一起运行
当前关闭()
mysql_conn.commit()
成功=正确
message=“Mysql查询成功:{}”。格式(query\u str)
除BaseException作为e外:
message=“Mysql错误:{};对于查询:{}”。格式(repr(e),query_str)
返回(成功、受影响的行数、结果行数、消息)
def执行带有重试的查询(查询str,值=None,num\u trys=3,消息=”):
#默认值
成功=错误
受影响的行数=0
结果_行=无
此消息=“执行查询时出错:{}”。格式(query\u str)
#我们还应该试试吗?
如果num_尝试小于1:
此\u message=“查询的尝试次数已用完:{}”。格式(query\u str)
返回(False、0、None、message+';'+此消息)
num\u尝试\u之后此=num\u尝试-1
#尝试执行查询
尝试:
(成功,受影响的行数,结果行,此消息)=执行查询(查询字符串,值)
除BaseException作为e外:
成功=错误
#处理成功或失败
如果success==True:
返回值(True、受影响的行数、结果行数、消息+“;”+此消息)
其他:
打开_new_mysql_connection()#使用密码等重新连接。
返回(执行带有重试的查询(查询str,value=value,num\u tries=num\u tries,在这个消息之后,message=(message+';'+这个消息)))

ping在运行查询之前被视为浪费资源且不可靠的反模式:@kiminoa-尝试执行查询并捕获任何MySQL错误,在这种情况下,您将重新尝试查询。ping在运行查询之前被视为浪费资源且不可靠的反模式: