捕捉在类中包装的调用中生成的 MySQL 警告

66 阅读3分钟

在使用 Python 编程语言时,我们可以使用 try/else 块来捕获代码执行过程中出现的异常。但是,当我们将 MySQL 查询语句封装在类中时,try/else 块却无法捕获 MySQL 生成的警告。

2. 解决方案

方法一:使用 Warning

我们可以通过使用 Warning 类来捕获 MySQL 生成的警告。Warning 类是 Python 标准库中一个内置类,它可以捕获所有类型的警告。以下是如何使用 Warning 类来捕获 MySQL 生成的警告的示例:

import MySQLdb
import sys
import copy
sys.path.append('../../config')
import credentials as c # local module with dbase connection credentials

class dbMySQL_Connection:
    def __init__(self, db_server, db_user, db_passwd):
        try:
            self.conn = MySQLdb.connect(db_server, db_user, db_passwd)
        except Warning as e:
            print(e)
        else:
            print("Connection established successfully.")

    def getCursor(self, dict_flag=True):
        try:
            self.dbMySQL_Cursor = dbMySQL_Cursor(self.conn, dict_flag)
            return self.dbMySQL_Cursor
        except Warning as e:
            print(e)

    def runQuery(self, qryStr, dict_flag=True):
        try:
            qry_res = runQueryNoCursor(qryStr=qryStr, \
                                       conn=self, \
                                       dict_flag=dict_flag)
            return qry_res
        except Warning as e:
            print(e)

class dbMySQL_Cursor:
    def __init__(self, conn, dict_flag=True):
        if dict_flag:
            try:
                dbMySQL_Cursor = conn.cursor(MySQLdb.cursors.DictCursor)
            except Warning as e:
                print(e)
        else:
            dbMySQL_Cursor = conn.cursor()
        self.dbMySQL_Cursor = dbMySQL_Cursor

    def closeCursor(self):
        try:
            self.dbMySQL_Cursor.close()
        except Warning as e:
            print(e)

def runQueryNoCursor(qryStr, conn, dict_flag=True):
    dbMySQL_Cursor = conn.getCursor(dict_flag)
    try:
        qry_res = runQueryFnc(qryStr, dbMySQL_Cursor.dbMySQL_Cursor)
        dbMySQL_Cursor.closeCursor()
        return qry_res
    except Warning as e:
        print(e)

def runQueryFnc(qryStr, dbMySQL_Cursor):
    qry_res              = {}
    try:
        qry_res['rows']      = dbMySQL_Cursor.execute(qryStr)
        qry_res['result']    = copy.deepcopy(dbMySQL_Cursor.fetchall())
        qry_res['messages']  = copy.deepcopy(dbMySQL_Cursor.messages)
        qry_res['query_str'] = qryStr
        return qry_res
    except Warning as e:
        print(e)

if __name__ == '__main__':
    qry = 'DROP DATABASE IF EXISTS database_of_armaments'
    dbConn = dbMySQL_Connection(**c.creds)

方法二:使用 warnings.catch_warnings() 函数

我们也可以通过使用 warnings.catch_warnings() 函数来捕获 MySQL 生成的警告。warnings.catch_warnings() 函数可以捕获所有类型的警告,包括 MySQL 生成的警告。以下是如何使用 warnings.catch_warnings() 函数来捕获 MySQL 生成的警告的示例:

import MySQLdb
import sys
import copy
import warnings
sys.path.append('../../config')
import credentials as c # local module with dbase connection credentials

class dbMySQL_Connection:
    def __init__(self, db_server, db_user, db_passwd):
        warnings.catch_warnings()
        warnings.filterwarnings("ignore", category=MySQLdb.Warning)
        self.conn = MySQLdb.connect(db_server, db_user, db_passwd)

    def getCursor(self, dict_flag=True):
        warnings.catch_warnings()
        warnings.filterwarnings("ignore", category=MySQLdb.Warning)
        self.dbMySQL_Cursor = dbMySQL_Cursor(self.conn, dict_flag)
        return self.dbMySQL_Cursor

    def runQuery(self, qryStr, dict_flag=True):
        warnings.catch_warnings()
        warnings.filterwarnings("ignore", category=MySQLdb.Warning)
        qry_res = runQueryNoCursor(qryStr=qryStr, \
                                   conn=self, \
                                   dict_flag=dict_flag)
        return qry_res

class dbMySQL_Cursor:
    def __init__(self, conn, dict_flag=True):
        warnings.catch_warnings()
        warnings.filterwarnings("ignore", category=MySQLdb.Warning)
        if dict_flag:
            dbMySQL_Cursor = conn.cursor(MySQLdb.cursors.DictCursor)
        else:
            dbMySQL_Cursor = conn.cursor()
        self.dbMySQL_Cursor = dbMySQL_Cursor

    def closeCursor(self):
        warnings.catch_warnings()
        warnings.filterwarnings("ignore", category=MySQLdb.Warning)
        self.dbMySQL_Cursor.close()

def runQueryNoCursor(qryStr, conn, dict_flag=True):
    warnings.catch_warnings()
    warnings.filterwarnings("ignore", category=MySQLdb.Warning)
    dbMySQL_Cursor = conn.getCursor(dict_flag)
    qry_res = runQueryFnc(qryStr, dbMySQL_Cursor.dbMySQL_Cursor)
    dbMySQL_Cursor.closeCursor()
    return qry_res

def runQueryFnc(qryStr, dbMySQL_Cursor):
    warnings.catch_warnings()
    warnings.filterwarnings("ignore", category=MySQLdb.Warning)
    qry_res              = {}
    qry_res['rows']      = dbMySQL_Cursor.execute(qryStr)
    qry_res['result']    = copy.deepcopy(dbMySQL_Cursor.fetchall())
    qry_res['messages']  = copy.deepcopy(dbMySQL_Cursor.messages)
    qry_res['query_str'] = qryStr
    return qry_res

if __name__ == '__main__':
    qry = 'DROP DATABASE IF EXISTS database_of_armaments'
    dbConn = dbMySQL_Connection(**c.creds)

方法三:使用 connection.set_character_set() 函数

我们可以通过使用 connection.set_character_set() 函数来捕获 MySQL 生成的警告。connection.set_character_set() 函数可以设置连接的字符集,也可以设置连接是否自动提交。以下是如何使用 connection.set_character_set() 函数来捕获 MySQL 生成的警告的示例:

import MySQLdb
import sys
import copy
sys.path.append('../../config')
import credentials as c # local module with dbase connection credentials

class dbMySQL_Connection:
    def __init__(self, db_server, db_user, db_passwd):
        self.conn = MySQLdb.connect(db_server, db_user, db_passwd)
        self.conn.set_character_set('utf8')
        self.conn.autocommit(True)

    def getCursor(self, dict_flag=True):
        self.dbMySQL_Cursor = dbMySQL_Cursor(self.conn, dict_flag)
        return self.dbMySQL_Cursor

    def runQuery(self, qryStr, dict_flag=True):
        qry_res = runQueryNoCursor(qryStr=qryStr, \
                                   conn=self, \
                                   dict_flag=dict_flag)
        return qry_res

class dbMySQL_Cursor:
    def __init__(self, conn, dict_flag=True):
        if dict_flag:
            dbMySQL_Cursor = conn.cursor(MySQLdb.cursors.DictCursor)
        else:
            dbMySQL_Cursor = conn.cursor()
        self.dbMySQL_Cursor = dbMySQL_Cursor

    def closeCursor(self):
        self.dbMySQL_Cursor.close()

def runQueryNoCursor(qryStr, conn, dict_flag=True):
    dbMySQL_Cursor = conn.getCursor(dict_flag)
    qry_res = runQueryFnc(qryStr, dbMySQL_Cursor.dbMySQL_Cursor)
    dbMySQL_Cursor.closeCursor()
    return qry_res

def runQueryFnc(qryStr, dbMySQL_Cursor):
    qry_res              = {}
    qry