Python: MySQL: Handling timeouts

后端 未结 3 1393
小鲜肉
小鲜肉 2021-01-13 09:02

I am using Python and mySQL, and there is a long lag between queries. As a result, I get an \'MySQL connection has gone away\' error, that is wait_timeout is exceeded.

相关标签:
3条回答
  • 2021-01-13 09:45

    I had the same problem and wanted to wrap the exception to capture it but instead I solved it by using the following. Before calling the execute, call
    self.con.ping(TRUE)

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

    I can no longer find the original source material I found this out from, but this solved the problem immediately.

    0 讨论(0)
  • 2021-01-13 09:50

    I tried Crasched's approach, which got me to a new OperationalError:

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

    My final solution was to first try the ping, and if another OperationalError was raised, to reconnect and recreate the cursor with the new connection, like so:

    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)
    

    Back in business!

    Python 2.7, MySQL 5.5.41

    0 讨论(0)
  • 2021-01-13 09:57

    I was running into mystifying "MySQL server has gone away" errors, and here is my solution.

    This solution will let you retry through MySQL errors, handle pretty much any type of query, include query variables in the query str or in a separate tuple, and collect and return all of the success and error messages you encounter along the way:

    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)))
    
    0 讨论(0)
提交回复
热议问题