有没有办法在pandas read_sql函数中设置超时?

问题描述 投票:0回答:2

我在 python 代码中通过 ODBC 连接连接到 DB2 服务器。 DB2 服务器为了维护而重新启动,或者在运行特定服务器端任务时断开连接,这种情况一天会发生 1 到 2 次。当时,如果我的代码开始执行 pandas read_sql 函数来获取查询结果,即使服务器在 1 小时后启动,它也会进入无限等待。

我想在 read_sql 的执行中设置超时,每当发生超时时,我想刷新与 DB2 服务器的连接,以便在继续查询之前再次建立新的连接。

我尝试过创建一个 while 循环并从 DB2 中选取数据块,而不是立即提取整个结果,但问题是如果 DB2 在提取块时断开连接,python 代码仍然会进入无限等待。

chunk_size = 1000    
offset = 0
while True:
        sql = "SELECT * FROM table_name limit %d offset %d" % (chunk_size,offset)
        df = pd.read_sql(sql, conn)
        df.index += (offset+1)
        offset += chunk_size
        sys.stdout.write('.')
        sys.stdout.flush()
        if df.shape[0] < chunk_size:
            break

如果 sql 执行时间超过 3 分钟,我需要 read_sql 抛出一些异常或返回一个值。如果发生这种情况,我需要连接到 DB2 才能刷新。

python-3.x pandas sqlalchemy odbc pyodbc
2个回答
10
投票

您可以使用该套件

func-timeout
。您可以通过 pip 安装,如下所示:

pip install func-timeout

因此,例如,如果您有一个函数“doit('arg1', 'arg2')”,您希望限制其运行时间为 5 秒,则可以使用 func_timeout 来调用它:

from func_timeout import func_timeout, FunctionTimedOut

try:
  doitReturnValue = func_timeout(5, doit, args=(‘arg1’, ‘arg2’))
except FunctionTimedOut:
  print ( “doit(‘arg1’, ‘arg2’) could not complete within 5 seconds, hence terminated.\n”)
except Exception as e:
  # Handle any exceptions that doit might raise here

0
投票

理论上您可以在数据库后端设置读取超时。例如,如果您将 sqlalchemy 与

pymysql
一起使用,则应该是:

from sqlalchemy import create_engine
eng = create_engine("mysql+pymysql://username:password@host:port/database",
    connect_args={'connect_timeout': 10.0, 'read_timeout': 180.0})

但是 read_timeout 在我的情况下不起作用。不确定这是否是 pymysql 的问题。如果您有不同的后端,请尝试查找连接器的文档并将相应的关键字 arg 传递给

connect_args
参数(也可能是
read_timeout

© www.soinside.com 2019 - 2024. All rights reserved.