【发布时间】:2017-07-16 21:41:13
【问题描述】:
我有一个用户定义的函数,它使用 pymysql 连接到 mysql 数据库,然后它询问数据库并将结果读入 Pandas 数据框。
import pandas as pd
import pymysql
import getpass
def myGetData(myQuery):
myServer = 'xxx.xxx.xxx.xxx'
myUser = input("Enter MySQL database username: ")
myPwd = getpass.getpass("Enter password: ")
myConnection = pymysql.connect(host=myServer,user=myUser,password=myPwd)
myTempDF = pd.io.sql.read_sql(myQuery, con=myConnection)
myConnection.close()
return myTempDF
myDF = myGetData("SELECT * FROM `myDB`.`myTable`")
我已经编写了代码来捕获由 pymysql.connect() 引起的异常,尽管为了清楚起见我没有在这里展示它。我还希望能够捕获可能由 read_sql() 引起的任何异常。在哪里可以找到可能引发的异常列表?它不在 Pandas 文档 (http://pandas.pydata.org/pandas-docs/version/0.19.2/generated/pandas.read_sql.html) 中,我在网上找不到任何提示。我可以捕获所有异常,但这似乎被 Python 社区普遍反对。我应该如何捕获 read_sql() 引发的异常?
编辑
我在这方面做了更多的工作,似乎即使我知道正在生成什么错误,捕捉异常也不是直截了当的。因此,例如,在上面给出的代码中,如果我输入的用户名和/或密码不正确,就会产生操作错误。最后一行或错误报告的内容如下:
OperationalError: (1045, "Access denied for user 'yyy'@'xxx.xxx.xxx.xxx' (using password: YES)")
我已经能够使用以下方法捕获此错误:
try:
phjConnection = pymysql.connect(host=phjServer, user=phjUser, password=phjPwd)
except pymysql.OperationalError as e:
print("\nAn OperationalError occurred. Error number {0}: {1}.".format(e.args[0],e.args[1]))
这很好用(尽管发现 OperationalError 需要使用 pymysql.OperationalError 来捕获是偶然的)。
现在,在函数的下一部分,Pandas 函数 real_sql() 使用上面创建的连接来运行 SQL 查询。如果我包含一个故意不正确的查询,该查询具有不正确的表名,则会发生另一个 OperationalError,然后是 DatabaseError:
OperationalError: (1142, "SELECT command denied to user 'yyy'@'xxx.xxx.xxx.xxx' for table 'table'")
During handling of the above exception, another exception occurred:
DatabaseError: Execution failed on sql 'SELECT * FROM `db`.`table`': (1142, "SELECT command denied to user 'yyy'@'xxx.xxx.xxx.xxx' for table 'table'")
但我现在完全不知道如何捕获第二个 OperationalError。之前使用的 pymysql.OperationalError 不起作用。我已经尝试了几乎所有我能想到的东西,但仍然无法捕捉到错误。错误消息不应该更多地说明错误是如何生成的以及如何捕获它吗?显然,我遗漏了一些明显的东西,但我找不到解决方案。任何建议将不胜感激。
编辑 2
作为对评论的回应,我现在捕获的异常如下:
import pandas as pd
import pymysql
import getpass
def myGetData(myQuery):
myServer = 'xxx.xxx.xxx.xxx'
myUser = input("Enter MySQL database username: ")
myPwd = getpass.getpass("Enter password: ")
try:
myConnection = pymysql.connect(host=myServer,user=myUser,password=myPwd)
except pymysql.OperationalError as e:
# Catching this exception works fine if, for example,
# I enter the wrong username and password
print("\nAn OperationalError occurred. Error number {0}: {1}.".format(e.args[0],e.args[1]))
try:
myTempDF = pd.io.sql.read_sql(myQuery, con=myConnection)
except pymysql.OperationalError as e:
# However, this error isn't picked up following an incorrect
# SQL query despite the error message saying that an
# OperationalError has occurred.
# Many variations on this theme have been tried but failed.
print("\nAn error occurred. Error number {0}: {1}.".format(e.args[0],e.args[1]))
myConnection.close()
return myTempDF
myDF = myGetData("SELECT * FROM `myDB`.`myTable`")
【问题讨论】:
-
您可以编辑代码以显示您现在如何处理错误吗?
-
添加了第二个编辑,以显示现在如何尝试捕获错误。
标签: python mysql python-3.x pandas pymysql