Pandas read_sql() 可以返回哪些异常
Posted
技术标签:
【中文标题】Pandas read_sql() 可以返回哪些异常【英文标题】:What exceptions could be returned from Pandas read_sql() 【发布时间】: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`")
【问题讨论】:
您可以编辑代码以显示您现在如何处理错误吗? 添加了第二个编辑,以显示现在如何尝试捕获错误。 【参考方案1】:好问题,注意,read_sql
是 'read_sql_table 和 read_sql_query 的包装器。通读source,ValueError
始终被抛出到父函数和辅助函数中。所以你可以安全地抓住ValueError
并妥善处理。 (请看源码)
【讨论】:
感谢您的建议...我去看看。 这是一个很好的提示 (++)。 @user1718097,您可能还想检查相应源文件中的 SQLAlchemy 异常(因为 Pandas 在to_sql()
中使用此模块)...
我在这个问题上做了更多的工作,并在原始问题中添加了一个编辑。【参考方案2】:
我只是在一个类似的问题中偶然发现了这个问题,并找到了从 SQLalchemy 中寻求异常的答案。
try:
df = pd.read_sql_query(QUERY, engine)
except sqlalchemy.exc.OperationalError as e:
logger.Info('Error occured while executing a query '.format(e.args))
更多信息可以在这里找到。 SQL Alchemy Docs
【讨论】:
只是我需要的信息,我将Operational
切换到 Programming
以进行 SQL 语法检查。 注意: 您也可以将诸如 execpt (sqlaclchemy.exc.ProgrammingError, sqlalchemy.exc.OperationalError) as e:
之类的 except 语句串起来以全部捕获以上是关于Pandas read_sql() 可以返回哪些异常的主要内容,如果未能解决你的问题,请参考以下文章
Python pandas read_sql 返回生成器对象