簡體   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