2012-02-24 21 views
8

Görünüşte düzgün bir durum var, ancak doğru bir çözüm bulamıyor.sqlalchemy: uzun süren bir sorguyu durdurma

Postgre'leri sorgulamak için sqlalchemy kullanıyorum. Bir istemci zaman aşımı gerçekleşirse, başka bir iş parçacığından uzun süre çalışan postgres sorgularını durdurmak/iptal etmek istiyorum. İş parçacığının Oturum veya Bağlantı nesnesine erişimi vardır. Ben denedim Bu noktada

:

session.bind.raw_connection().close() 

ve

session.connection().close() 

ve

session.close 

ve

session.transaction.close() 

Ama ne deneyeceğim, postgres sorgulama bitene kadar devam ediyor. Bunu en tepede pg izleyerek biliyorum. Bunun yapılması çok kolay değil mi? Ben bir şey özlüyorum Bu pid almak ve doğrudan bir stop sinyali göndermek imkansız mı?

+0

tamamen müşteri işlemini öldürsen bile, veritabanı bunun ne olduğuna bağlı olarak, sorgu geri almak için uzun bir zaman alabilir Tabloda ne kadar veri var. Sorguları optimize etmek yerine, onları nasıl iptal edeceğinizi anlamaya çalışın. – wberry

+0

Evet, optimizasyon en önemlisidir, ancak projemizin doğası gereği zaman aşımları gerçekleşecek ve tüm üsleri kapsadığından emin olmak isteriz. Yorumun için teşekkürler. –

+0

Ham sokete erişmenin yolu, kapatmak için psycopg2 sürücüsünde bir yere gömülecek. Bunu bulmak için bunun kaynağını incelemelisiniz. Gerçekleştirilemeyen davranışlar ve sqlalchemy katmanındaki sert çökmeler için tam olarak hazır olun. – wberry

cevap

6

Bu şimdiye kadar, iyi iş gibi görünüyor:

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