python MySQLDB查询超时

标签 python timeout mysql

我正在尝试对 python MySQLDB 中的查询实现时间限制。我有一种情况,我无法控制查询,但需要确保它们不会超过设定的时间限制。我试过使用 signal.SIGALRM 来中断执行调用,但这似乎不起作用。信号被发送,但直到执行调用完成后才被捕获。

我写了一个测试用例来证明这个行为:

#!/usr/local/bin/python2.6

import time
import signal

from somewhere import get_dbc

class Timeout(Exception):
    """ Time Exceded """

def _alarm_handler(*args):
    raise Timeout

dbc = get_dbc()

signal.signal(signal.SIGALRM, _alarm_handler)
signal.alarm(1)

try:
    print "START:  ", time.time()
    dbc.execute("SELECT SLEEP(10)")
except Timeout:
    print "TIMEOUT!", time.time()'

“SELECT SLEEP(10)”正在模拟一个慢速查询,但我确实看到了与实际慢速查询相同的行为。

结果:

START:   1254440686.69
TIMEOUT! 1254440696.69

如您所见,它休眠了 10 秒,然后我得到了超时异常。

问题:

  1. 为什么直到执行完成后我才收到信号?
  2. 还有其他可靠的方法来限制查询执行时间吗?

最佳答案

@nosklo's twisted-based solution优雅且可行,但如果您想避免对扭曲的依赖,该任务仍然可行,例如:

import multiprocessing

def query_with_timeout(dbc, timeout, query, *a, **k):
  conn1, conn2 = multiprocessing.Pipe(False)
  subproc = multiprocessing.Process(target=do_query,
                                    args=(dbc, query, conn2)+a, 
                                    kwargs=k)
  subproc.start()
  subproc.join(timeout)
  if conn1.poll():
    return conn1.recv()
  subproc.terminate()
  raise TimeoutError("Query %r ran for >%r" % (query, timeout))

def do_query(dbc, query, conn, *a, **k):
  cu = dbc.cursor()
  cu.execute(query, *a, **k)
  return cu.fetchall()

关于python MySQLDB查询超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1507091/

相关文章:

python - Django Map Widgets 绘制多边形

api - 来自 k8s 主节点的集群 IP 的连接受损/延迟

mysql - 从 MySQL 安装程序下载 MySQL Server 时失败

python - Qubole 中的宽数据 PySpark 机器学习

python按指定次数拆分

android mediaplayer mediacontroller超时

sql-server - 从 SQL Server 新建的表中获取记录时出现超时错误

php - 如何将数组值添加到 MySQL 查询?

PHP 和 MySQL : Date + Time Storage

Python os.walk 始终附加 root