繁体   English   中英

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

[英]sqlalchemy: stopping a long-running query

我有一个看似简单的情况,但找不到直接的解决方案。

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

此时我已经尝试过:

session.bind.raw_connection().close()

session.connection().close()

session.close

session.transaction.close()

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

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

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()

来源

对于那些可能已经在这里结束的 MySQL 人员来说,这个答案的修改版本可以杀死来自第二个连接的查询。 基本上如下,假设引擎盖下的 pymysql:

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

原始连接会引发 pymysql.err.OperationalError。 有关创建长时间运行的测试查询的巧妙方法,请参阅其他答案。

在 MYSQL 上发现可以指定查询优化器提示。 一个这样的提示是 MAX_EXECUTION_TIME 指定查询在终止前应该执行多长时间。

您可以在 app.py 中添加它

@event.listens_for(engine, 'before_execute', retval=True)
def intercept(conn, clauseelement, multiparams, params):
  from sqlalchemy.sql.selectable import Select

  # check if it's select statement
  if isinstance(clauseelement, Select):
    # 'froms' represents list of tables that statement is querying
    table = clauseelement.froms[0]
    '''Update the timeout here in ms (1s = 1000ms)'''
    timeout_ms = 4000
    # adding filter in clause
    clauseelement = clauseelement.prefix_with(f"/*+ MAX_EXECUTION_TIME({timeout_ms}) */", dialect="mysql")

  return clauseelement, multiparams, params

SQLAlchemy 查询 API 无法使用提示MYSQL 参考正常工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM