python mysql斷開重連的實(shí)現(xiàn)方法
后臺(tái)服務(wù)在運(yùn)行時(shí)發(fā)現(xiàn)一個(gè)問題,運(yùn)行約15分鐘后,接口請(qǐng)求報(bào)錯(cuò)
pymysql.err.InterfaceError: (0, '')
這個(gè)錯(cuò)誤提示一般發(fā)生在將None賦給多個(gè)值,定位問題時(shí)發(fā)現(xiàn)
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')
如何解決這個(gè)問題呢
出現(xiàn)問題的代碼
class MysqlConnection(object): """ mysql操作類,對(duì)mysql數(shù)據(jù)庫進(jìn)行增刪改查 """ def __init__(self, config): # Connect to the database self.connection = pymysql.connect(**config) self.cursor = self.connection.cursor() def Query(self, sql): """ 查詢數(shù)據(jù) :param sql: :return: """ self.cursor.execute(sql) return self.cursor.fetchall()
在分析問題前,先看看Python 數(shù)據(jù)庫的Connection、Cursor兩大對(duì)象
Python 數(shù)據(jù)庫圖解流程

Connection、Cursor形象比喻

Connection()的參數(shù)列表
- host,連接的數(shù)據(jù)庫服務(wù)器主機(jī)名,默認(rèn)為本地主機(jī)(localhost)
- user,連接數(shù)據(jù)庫的用戶名,默認(rèn)為當(dāng)前用戶
- passwd,連接密碼,沒有默認(rèn)值
- db,連接的數(shù)據(jù)庫名,沒有默認(rèn)值
- conv,將文字映射到Python類型的字典
- cursorclass,cursor()使用的種類,默認(rèn)值為MySQLdb.cursors.Cursor
- compress,啟用協(xié)議壓縮功能
- named_pipe,在windows中,與一個(gè)命名管道相連接
- init_command,一旦連接建立,就為數(shù)據(jù)庫服務(wù)器指定一條語句來運(yùn)行
- read_default_file,使用指定的MySQL配置文件
- read_default_group,讀取的默認(rèn)組
- unix_socket,在unix中,連接使用的套接字,默認(rèn)使用TCP
- port,指定數(shù)據(jù)庫服務(wù)器的連接端口,默認(rèn)是3306

connection對(duì)象支持的方法

Cursor對(duì)象支持的方法
用于執(zhí)行查詢和獲取結(jié)果

execute方法:執(zhí)行SQL,將結(jié)果從數(shù)據(jù)庫獲取到客戶端

調(diào)試代碼,將超時(shí)時(shí)間設(shè)置較長
self.connection._write_timeout = 10000
發(fā)現(xiàn)并沒有生效
使用try...except... 方法捕獲失敗后重新連接數(shù)據(jù)庫
try: self.cursor.execute(sql) except: self.connection() self.cursor.execute(sql)
直接拋出異常,并沒有執(zhí)行except代碼段
打印self.connection ,輸出如下:
<pymysql.connections.Connection object at 0x0000000003E2CCC0>
拋出異常重新connect是不行的,因?yàn)?code>connections 仍存在未失效
找到一種方法可以解決問題,在每次連接之前,判斷該鏈接是否有效,pymysql提供的接口是 Connection.ping()
這個(gè)該方法的源碼
def ping(self, reconnect=True):
"""Check if the server is alive"""
if self._sock is None:
if reconnect:
self.connect()
reconnect = False
else:
raise err.Error("Already closed")
try:
self._execute_command(COMMAND.COM_PING, "")
return self._read_ok_packet()
except Exception:
if reconnect:
self.connect()
return self.ping(False)
else:
raise
在每次請(qǐng)求數(shù)據(jù)庫前執(zhí)行如下代碼
def reConnect(self): try: self.connection.ping() except: self.connection()
不過這樣的方式雖然能解決問題,但是感覺相對(duì)較low,希望有更好的處理方法
目前已實(shí)現(xiàn)的數(shù)據(jù)庫查詢這部分的代碼
import pymysql
class DBManager(object):
def __init__(self,config):
self.connection = pymysql.connect(**config) # config為數(shù)據(jù)庫登錄驗(yàn)證配置信息
self.cursor = self.connection.cursor()
def query(self, sql, params):
try:
with self.connection.cursor() as cursor:
cursor.execute(sql, params)
result = cursor.fetchall()
self.connection.commit()
return result
# self.connection.close()
except Exception as e:
traceback.print_exc()
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python中線程threading.Thread的使用詳解
python的thread模塊是比較底層的模塊,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用。本文將為大家詳細(xì)介紹一下python中的線程threading.Thread()的使用,需要的可以參考一下2022-07-07
PyCharm設(shè)置SSH遠(yuǎn)程調(diào)試的方法
這篇文章主要介紹了PyCharm設(shè)置SSH遠(yuǎn)程調(diào)試的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
使用原生Python編寫Hadoop?MapReduce程序
在大數(shù)據(jù)處理領(lǐng)域,Hadoop?MapReduce是一個(gè)廣泛使用的框架,用于處理和生成大規(guī)模數(shù)據(jù)集,本文將使用原生Python編寫Hadoop?MapReduce程序,需要的可以參考下2025-02-02
pycharm解決關(guān)閉flask后依舊可以訪問服務(wù)的問題
這篇文章主要介紹了pycharm解決關(guān)閉flask后依舊可以訪問服務(wù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04

