2015-01-29 9 views
7

http://docs.sqlalchemy.org/en/rel_0_9/core/pooling.html#disconnect-handling-pessimistic'a göre, SQLAlchemy, bağlantı havuzundaki bir girdinin artık geçerli olmaması durumunda yeniden bağlanmak için kullanılabilir. "Ping sunucu" terminali üzerinde yazılı olduğu için güvenli görünüyor SQLAlchemy'ın bağlantı kesilmesinden nasıl kurtarılacağı öğretilebilir?

sqlalchemy.exc.OperationalError: (OperationalError) terminating connection due to administrator command 
server closed the connection unexpectedly 
     This probably means the server terminated abnormally 
     before or while processing the request. 

sonucuna: Bu özel durumu alıyorsunuz Ama bunun yerine kurtarma

import subprocess 
from sqlalchemy import create_engine, event 
from sqlalchemy import exc 
from sqlalchemy.pool import Pool 

@event.listens_for(Pool, "checkout") 
def ping_connection(dbapi_connection, connection_record, connection_proxy): 
    cursor = dbapi_connection.cursor() 
    try: 
     print "pinging server" 
     cursor.execute("SELECT 1") 
    except: 
     print "raising disconnect error" 
     raise exc.DisconnectionError() 
    cursor.close() 

engine = create_engine('postgresql://[email protected]/test') 

connection = engine.connect() 

subprocess.check_call(['psql', str(engine.url), '-c', 
    "select pg_terminate_backend(pid) from pg_stat_activity " + 
    "where pid <> pg_backend_pid() " + 
    "and datname='%s';" % engine.url.database], 
    stdout=subprocess.PIPE) 

result = connection.execute("select 'OK'") 
for row in result: 
    print "Success!", " ".join(row) 

: Bunu test etmek için aşağıdaki test vakası oluşturun olay dinleyicisi eklenmiştir. SQLAlchemy'ın bir bağlantı kesmeden nasıl kurtarılacağı öğretilebilir? checkout yöntem sonradan bağlantınızı kaybederseniz öncelikle havuz (örn sizin connection = engine.connect() hat)

bir bağlantı olsun sadece denilen olduğu gibi

cevap

4

Bu kadar açıkça değiştirmek zorunda kalacak görünüyor

: gibi bir şey kullanarak veritabanı sorgularını sarmak böylece, bu sql her bit etrafında yapmak için bir ağrı olurdu

try: 
    result = connection.execute("select 'OK'") 
except sqlalchemy.exc.OperationalError: # may need more exceptions here 
    connection = engine.connect() # grab a new connection 
    result = connection.execute("select 'OK'") # and retry 

: Eğer sadece bir yenisini yakala ve sql yeniden olabilir

def db_execute(conn, query): 
    try: 
     result = conn.execute(query) 
    except sqlalchemy.exc.OperationalError: # may need more exceptions here (or trap all) 
     conn = engine.connect() # replace your connection 
     result = conn.execute(query) # and retry 
    return result 

aşağıdadır:

result = db_execute(connection, "select 'OK'") 

şimdi başarılı mı.

Diğer bir seçenek de invalidate yöntemi için dinlemek ve bağlantınızı yerine o zaman bir işlem yapmaya olacaktır.

+2

SQLAlchemy belgelerinin yanıltıcı olduğunu onaylamış görünüyorsunuz. hiçbir değeri bu bağlamda _Pool_ her sorgu bir yardımcı yönteminde sarılmış gerekiyorsa yapar durum işleme ve açık kurtarma yapar. – eradman