Python和MySQLdb警告
我有一个程序,它的功能是把MSSQL的数据导出,然后导入到MySQL里。我有一个导入的函数,具体是这样的:
def importMySql (mycursor,exportedfilename,table,delimiter):
file_loc = str(sys.path[0] +"\\" +exportedfilename.lower()+".out").replace("\\", "\\\\")
mycursor.execute("LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' LINES TERMINATED BY '\r\n'" %(str(file_loc), table, delimiter))
在使用MySQLdb的时候,它会出现一些警告:
C:\Users\tfy\Documents\PyProj\UTL (Export, Import, RDF)\eic.py:98: Warning: Data truncated for column 'DateofCharges' at row 1194
mycursor.execute("LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' LINES TERMINATED BY '\r\n'" %(str(file_loc), table, delimiter))
C:\Users\tfy\Documents\PyProj\UTL (Export, Import, RDF)\eic.py:98: Warning: Data truncated for column 'DateofCharges' at row 2009
mycursor.execute("LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' LINES TERMINATED BY '\r\n'" %(str(file_loc), table, delimiter))
C:\Users\tfy\Documents\PyProj\UTL (Export, Import, RDF)\eic.py:98: Warning: Data truncated for column 'DateofCharges' at row 4793
mycursor.execute("LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' LINES TERMINATED BY '\r\n'" %(str(file_loc), table, delimiter))
但我希望能控制这些警告,只输出:
Warning: Data truncated for column 'DateofCharges' at row 1194
Warning: Data truncated for column 'DateofCharges' at row 2009
Warning: Data truncated for column 'DateofCharges' at row 4739
我查了很多资料,发现有不少信息讲解了如何创建自定义的警告。不过,我不太确定怎么才能实现我想要的效果。我并不想关闭警告,只是想“格式化”一下它们。我考虑过直接修改MySQLdb的文件,但它是以.egg格式存在的,无法直接编辑。我也尝试过使用warning.format()
,但没有成功。
谢谢!
4 个回答
你可以在一个子进程中运行你的mysql代码吗?如果可以的话,你可以使用Python的subprocess模块来运行mysql代码,从标准输出中读取结果,并进行相应的格式化。比如,你可以使用process.stdout.readline()
来读取一行输出。
你可以参考这个问题:通过STDIN/STDOUT使用Python启动和控制外部进程
使用 MySQLdb
你可以通过一种叫做“猴子补丁”的方法来修改 MySQLdb,以实现这个功能:
import types
def warning_check(self):
if not self._warnings:
self.messages = ()
return
self.messages = self._get_db().show_warnings()
然后在你的函数里像这样修改 Cursor 对象:
cur._warning_check = types.MethodType(warning_check, cur)
接着,当你执行完 LOAD DATA..
后,可以打印出相关信息:
cur.execute("LOAD DATA..")
for msg in cur.messages:
print "Warning: {msg}".format(msg=msg[2])
使用 MySQL Connector/Python
如果你用 MySQL Connector/Python,可以这样做:
cnx.get_warnings = True
cur.execute("LOAD DATA..")
for msg in cur.fetchwarnings():
print "Warning: {msg}".format(msg=msg[2])
(注意,你需要在连接参数中设置客户端标志 client_flags=[mysql.connector.ClientFlag.LOCAL_FILES]
)
弄明白怎么使用pprint。根据提问者的解决方案,默认的警告需要被抑制,然后添加一个show_warnings的函数,最后使用新的打印格式。
from warnings import filterwarnings
import MySQLdb as mdb
from pprint import pprint
filterwarnings('ignore', category = mdb.Warning)
con = mdb.connect(...)
cur = con.cursor()
query = "Update table ..."
cur.execute(query)
con.commit()
warnings = con.show_warnings() # return in tuple type
pprint(warnings, width=100, depth=2) # width is the num of characters in each line, and depth is the level of the warnings in the tuple
这是我找到的最简单的方法……我也不知道为什么我一开始没想到这一点……我只是把光标发出的警告给屏蔽掉了:
import warnings
warnings.filterwarnings("ignore", category = MySQLdb.Warning)
然后我把这段代码加到了我的 importMySql 函数里:
mycursor.execute("SHOW WARNINGS")
warnings = mycursor.fetchall()
for i in range(len(warnings)):
print "Warning - " +warnings[i][2]