2012-02-24 15 views
8

私は一見単純な状況ですが、簡単な解決策が見つかりません。sqlalchemy:長期実行クエリの停止

私はpostgresを照会するためにsqlalchemyを使用しています。クライアントのタイムアウトが発生した場合は、別のスレッドから長い実行中のpostgresクエリを停止/キャンセルしたいと思います。スレッドはSessionオブジェクトまたはConnectionオブジェクトにアクセスできます。私が試したこの時点で

session.bind.raw_connection().close() 

session.connection().close() 

session.close 

session.transaction.close() 

しかし私が何を試みても、postgresのクエリはそれが終わるまで続けられます。私は一番上のpgを見てこれを知っています。これはかなり簡単ではありませんか?私は何かが欠けている?これは、PIDを取得し、直接停止信号を送信せずに不可能ですか?

+0

あなたは完全にあなたのクライアントのプロセスを強制終了しても、データベースがどのようなそれに応じて、そのクエリをロールバックするのに長い時間がかかる場合がありますどのくらいのデータがテーブル内にあるのかを示します。クエリーを中止する方法を見つけようとするのではなく、クエリを最適化する作業をしてください。 – wberry

+0

はい、最適化が最も重要ですが、プロジェクトタイムアウトの性質上、すべての基盤をカバーしていることを確認したいと思います。ご意見ありがとうございます。 –

+0

rawソケットにアクセスして終了させる方法は、psycopg2ドライバのどこかに埋め込まれます。あなたはそれを見つけるためにソースを見直さなければならないでしょう。 sqlalchemyレイヤーで説明できない動作やハードクラッシュが発生した場合は、実際にソケットの1つを強制的に閉じる直前に完全に準備してください。 – wberry

答えて

6

これはこれまでのところ、うまく動作しているようです:

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

関連する問題