文章内容
2020/11/4 11:16:41,作 者: 黄兵
MySQLdb._exceptions.OperationalError: (2006, '')
今天在使用Python删除数据的时候出现如下错误:
MySQLdb._exceptions.OperationalError: (2006, '')
出现错误的原因:
由于在前面使用的查询语句查询出结果之后,关闭连接,之后后面再次连接,已经关闭连接所以出现了这个问题。
下面是源代码:
class CleanAccessLogMain: """ 清理用户访问历史记录 """ def __init__(self): init_config = conn_config.ConnConfig() self._local_mysql = init_config.Conn_Local_MySQL() self._remote_mysql = init_config.Conn_MySQL() # restore log logger_name = 'clean_access_log' self._logger = LoggingConfig.init_logging(logger_name) self._temp_list_id = [] def read_remote_access_log(self): # init_config = conn_config.ConnConfig() # with closing(init_config.Conn_MySQL()) as mysql_conn: with closing(self._remote_mysql) as mysql_conn: with closing(mysql_conn.cursor()) as cur: # 查询2019年全年数据 sql = "SELECT * FROM SMS_Receive_Production.access_log JOIN (SELECT id FROM SMS_Receive_Production.access_log LIMIT 1000 OFFSET 0) AS t1 ON (t1.id=access_log.id);" # 执行SQL语句 try: cur.execute(sql) # 获取所有记录列表 results = cur.rowcount except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'执行 read_remote_access_log 函数时,SQL命令查询的时候出现错误,具体错误内容: {e}') return False if results == 0: # 数据是0,说明2018年数据已经完全删除,结束 print('数据已经清理完成') return False else: # 查询结果插入sms_content_info和sms_content表 get_all = cur.fetchall() temp_list = [] for item in get_all: id = item[0] time = item[1] ip = item[2] url = item[3] user_agent = item[4] referer = item[5] temp_list.append([time, ip, url, user_agent, referer]) self._temp_list_id.append(id) return temp_list def write_local_access_log(self): # 将软成数据写入到本地数据库 with closing(self._local_mysql) as mysql_conn: with closing(mysql_conn.cursor()) as cur: sql = "INSERT INTO access_log(TIME, IP, URL, USER_AGENT, REFERER) VALUES (%s,%s,%s,%s,%s);" data_list = self.read_remote_access_log() try: cur.executemany(sql, data_list) except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'插入Access_Log出现错误,具体错误内容: {e}') mysql_conn.commit() # 数据提交之后清历史记录 self.delete_remote_access_log() def delete_remote_access_log(self): with closing(self._remote_mysql) as mysql_conn: with closing(mysql_conn.cursor()) as cur: if self._temp_list_id is not None: for item in self._temp_list_id: sql = f"DELETE FROM access_log WHERE id='{item}';" try: # 删除数据 cur.execute(sql) except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'删除Access_Log出现错误,具体错误内容: {e}') mysql_conn.commit() # 删除完成之后,清空列表 self._temp_list_id.clear()
可以看到read_remote_access_log
执行完成之后即关闭数据库连接,之后delete_remote_access_log
再次执行删除操作的时候,还是用的初始化连接,此时链接已经关闭,就会出现错误。
解决方案:
重新设置read_remote_access_log
和delete_remote_access_log
的独立连接,避免连接重用:
class CleanAccessLogMain: """ 清理用户访问历史记录 """ def __init__(self): init_config = conn_config.ConnConfig() self._local_mysql = init_config.Conn_Local_MySQL() self._remote_mysql = init_config.Conn_MySQL() # restore log logger_name = 'clean_access_log' self._logger = LoggingConfig.init_logging(logger_name) self._temp_list_id = [] def read_remote_access_log(self): init_config = conn_config.ConnConfig() with closing(init_config.Conn_MySQL()) as mysql_conn: with closing(mysql_conn.cursor()) as cur: # 查询2019年全年数据 sql = "SELECT * FROM SMS_Receive_Production.access_log JOIN (SELECT id FROM SMS_Receive_Production.access_log LIMIT 1000 OFFSET 0) AS t1 ON (t1.id=access_log.id);" # 执行SQL语句 try: cur.execute(sql) # 获取所有记录列表 results = cur.rowcount except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'执行 read_remote_access_log 函数时,SQL命令查询的时候出现错误,具体错误内容: {e}') return False if results == 0: # 数据是0,说明2018年数据已经完全删除,结束 print('数据已经清理完成') return False else: # 查询结果插入sms_content_info和sms_content表 get_all = cur.fetchall() temp_list = [] for item in get_all: id = item[0] time = item[1] ip = item[2] url = item[3] user_agent = item[4] referer = item[5] temp_list.append([time, ip, url, user_agent, referer]) self._temp_list_id.append(id) return temp_list def write_local_access_log(self): # 将软成数据写入到本地数据库 with closing(self._local_mysql) as mysql_conn: with closing(mysql_conn.cursor()) as cur: sql = "INSERT INTO access_log(TIME, IP, URL, USER_AGENT, REFERER) VALUES (%s,%s,%s,%s,%s);" data_list = self.read_remote_access_log() try: cur.executemany(sql, data_list) except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'插入Access_Log出现错误,具体错误内容: {e}') mysql_conn.commit() # 数据提交之后清历史记录 self.delete_remote_access_log() def delete_remote_access_log(self): with closing(self._remote_mysql) as mysql_conn: with closing(mysql_conn.cursor()) as cur: if self._temp_list_id is not None: for item in self._temp_list_id: sql = f"DELETE FROM access_log WHERE id='{item}';" try: # 删除数据 cur.execute(sql) except (MySQLdb.Error, MySQLdb.Warning) as e: self._logger.error(f'删除Access_Log出现错误,具体错误内容: {e}') mysql_conn.commit() # 删除完成之后,清空列表 self._temp_list_id.clear()
这样问题就解决了。
黄兵个人博客原创。
转载请注明出处:黄兵个人博客 - MySQLdb._exceptions.OperationalError: (2006, '')
评论列表