2012-02-24 40 views
8

Tôi có tình huống dường như thẳng thắn nhưng không thể tìm thấy giải pháp thẳng về phía trước.sqlalchemy: dừng truy vấn dài hạn

Tôi đang sử dụng sqlalchemy để truy vấn postgres. Nếu thời gian chờ của khách hàng xảy ra, tôi muốn dừng/hủy các truy vấn postgres đang chạy dài từ một chuỗi khác. Chủ đề có quyền truy cập vào đối tượng Session hoặc Connection.

Tại thời điểm này tôi đã cố gắng:

session.bind.raw_connection().close() 

session.connection().close() 

session.close 

session.transaction.close() 

Nhưng bất kể tôi thử gì, truy vấn postgres vẫn tiếp tục cho đến khi kết thúc. Tôi biết điều này từ xem pg ở đầu trang. Điều này không dễ làm sao? Tôi đang thiếu một cái gì đó? Điều này là không thể mà không nhận được pid và gửi tín hiệu dừng trực tiếp?

+0

Thậm chí nếu bạn giết quá trình khách hàng của bạn hoàn toàn, cơ sở dữ liệu có thể mất một thời gian dài để quay trở lại truy vấn của mình, tùy thuộc vào những gì nó và số lượng dữ liệu trong bảng. Làm việc tối ưu hóa các truy vấn của bạn thay vì cố gắng tìm ra cách hủy bỏ chúng. – wberry

+0

Có, tối ưu hóa là quan trọng nhất, nhưng do tính chất của thời gian chờ dự án của chúng tôi sẽ xảy ra và chúng tôi muốn đảm bảo rằng chúng tôi đang bao gồm tất cả các cơ sở. Cám ơn bạn đã góp ý. –

+0

Cách để truy cập vào ổ cắm thô, để đóng nó, sẽ được chôn cất ở đâu đó trong trình điều khiển psycopg2. Bạn sẽ phải xem lại mã nguồn để tìm nó. Được chuẩn bị đầy đủ cho hành vi không thể giải thích và sự cố cứng tại lớp sqlalchemy, bắt đầu ngay lập tức bạn thực sự buộc đóng một trong các ổ cắm. – wberry

Trả lời

6

Điều này dường như làm việc tốt, cho đến nay:

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

Các vấn đề liên quan