sqlalchemy:停止长时间运行的查询

时间:2012-02-24 20:23:03

标签: python django sqlalchemy postgresql

我看似直截了当,但无法找到直接的解决方案。

我正在使用sqlalchemy来查询postgres。如果发生客户端超时,我想从另一个线程停止/取消长时间运行的postgres查询。该线程可以访问Session或Connection对象。

此时我尝试过:

session.bind.raw_connection().close()

session.connection().close()

session.close

session.transaction.close()

但无论我尝试什么,postgres查询仍然会继续,直到它结束。我从顶部看pg就知道这一点。这不是很容易吗?我错过了什么?如果没有获得pid并直接发送停止信号,这是不可能的吗?

2 个答案:

答案 0 :(得分:7)

到目前为止,这似乎运作良好:

def test_close_connection(self):
    import threading
    from psycopg2.extensions import QueryCanceledError
    from sqlalchemy.exc import DBAPIError

    session = Session()
    conn = session.connection()
    sql = self.get_raw_sql_for_long_query()

    seconds = 5
    t = threading.Timer(seconds, conn.connection.cancel)
    t.start()

    try:
        conn.execute(sql)
    except DBAPIError, e:
        if type(e.orig) == QueryCanceledError:
            print 'Long running query was cancelled.'
    t.cancel()

source

答案 1 :(得分:0)

对于那些可能已经在这里结束的MySQL人员而言,可以使用this答案的修改版本来终止第二个连接的查询。本质上讲,假设pymysql处于后台:

thread_id = conn1.connection.thread_id()
t = threading.Timer(seconds, lambda: conn2.execute("kill {}".format(thread_id)))

原始连接将引发pymysql.err.OperationalError。有关创建长期运行的查询以进行测试的巧妙方法,请参见this其他答案。