2010-01-01 20 views
17

Python'da, çoğunlukla eğlenmek için küçük bir veritabanı bağdaştırıcısı yazıyorum. Kodun, MySQL bağlantısının "kaybolup gitmediği" bir durumdan kurtarılmaya çalışıyorum, yani wait_timeout. wait_timeout'u 10'a ayarladıktan sonra bunu deneyebilirim. On saniye bekleyin ve bir istek yapmayaZarif bir şekilde işleme "MySQL gitti"

def select(self, query, params=[]): 
     try: 
      self.cursor = self.cxn.cursor() 
      self.cursor.execute(query, params) 
     except MySQLdb.OperationalError, e: 
      if e[0] == 2006: 
       print "We caught the exception properly!" 
       print self.cxn 
       self.cxn.close() 
       self.cxn = self.db._get_cxn() 
       self.cursor = self.cxn.cursor() 
       self.cursor.execute(query, params) 
       print self.cxn 

     return self.cursor.fetchall() 

Sonraki:

İşte benim kod. İşte CherryPy gibi görünüyor:

[31/Dec/2009:20:47:29] ENGINE Bus STARTING 
[31/Dec/2009:20:47:29] ENGINE Starting database pool... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE POOL Connecting to MySQL... 
[31/Dec/2009:20:47:29] ENGINE Started monitor thread '_TimeoutMonitor'. 
[31/Dec/2009:20:47:29] ENGINE Started monitor thread 'Autoreloader'. 
[31/Dec/2009:20:47:30] ENGINE Serving on 0.0.0.0:8888 
[31/Dec/2009:20:47:30] ENGINE Bus STARTED 
We caught the exception properly! <====================================== Aaarg! 
<_mysql.connection open to 'localhost' at 1ee22b0> 
[31/Dec/2009:20:48:25] HTTP Traceback (most recent call last): 
    File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-py2.6.egg/cherrypy/_cprequest.py", line 606, in respond 
cherrypy.response.body = self.handler() 
    File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-py2.6.egg/cherrypy/_cpdispatch.py", line 25, in __call__ 
    return self.callable(*self.args, **self.kwargs) 
    File "adp.py", line 69, in reports 
    page.sources = sql.GetSources() 
    File "/home/swoods/dev/adp/sql.py", line 45, in __call__ 
    return getattr(self.formatter.cxn, parsefn)(sql, sql_vars) 
    File "/home/swoods/dev/adp/database.py", line 96, in select 
    self.cursor.execute(query, params) 
    File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler 
    raise errorclass, errorvalue 
OperationalError: (2006, 'MySQL server has gone away') 

[31/Dec/2009:20:48:25] HTTP 
Request Headers: 
    COOKIE: session_id=e14f63acc306b26f14d966e606612642af2dd423 
    HOST: localhost:8888 
    CACHE-CONTROL: max-age=0 
    ACCEPT: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 
    ACCEPT-CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.3 
    USER-AGENT: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/532.5 (KHTML, like  Gecko) Chrome/4.0.249.43 Safari/532.5 
    CONNECTION: keep-alive 
    Remote-Addr: 127.0.0.1 
    ACCEPT-LANGUAGE: en-US,en;q=0.8 
    ACCEPT-ENCODING: gzip,deflate 
127.0.0.1 - - [31/Dec/2009:20:48:25] "GET /reports/1 HTTP/1.1" 500 1770 "" "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.43 Safari/532.5" 

neden görünmüyor bu iş ?? İstisnaları açıkça yakalarım, hem bağlantıyı hem de imleci yeniden oluşturuyorum, ama hala işe yaramıyor. MySQLdb'nin bağlantıları nasıl aldığı ile ilgili mi?

cevap

12

Koddan göremiyorum, ancak tahminim, db._get_cxn() yönteminin bir bağlantı havuzu oluşturma ve yeni bir tane oluşturmak yerine varolan bağlantı nesnesini döndürmesidir. Mevcut faydasız bağlantıyı temizlemek için db üzerinde yapabileceğiniz bir çağrı yok mu? (Ve gerçekten bir iç _ -prefixed yöntemini çağırıyor olmalısınız?)

MySQL has gone away önlemek için Genellikle kullandığım son kez bağlantı ile bir zaman damgası tutmayı tercih ediyorum. Daha sonra tekrar kullanmaya çalışmadan önce, zaman damgasına bakıyorum ve son birkaç saatten daha önce kullanılmışsa bağlantıyı kapatın/atın. Bu, olası tüm sorguları try...except OperationalError...try again ile kaydeder.

+0

Doğru her iki hesaptasınız. Bu şey birçok farklı yöne gitti. Aslında, paragraf 2'deki öneriyi uygulamıştım ve bu benim tercih ettiğim şeylerden biri. Birinci paragrafta önerdiğin hatayı düzeltmek için kodu yeniden yazdım (hata tam olarak bu oldu ... Kendi refakatçimin kurbanıyım). Yardımlarınız için çok teşekkürler. Mutlu Yıllar! –

+5

@SeanWoods - Düzeltilen kodunuzu paylaşabilir misiniz? Yaptığın aynı sorundan acı çekiyorum ... – Jonathan

+0

@SeanWoods Kodu paylaşmanın herhangi bir fikrini verdin mi? Aynı hatadan da muzdarip gibi görünüyor. İlk denemem için 3 kez denemeliyim, fakat bobince bahsettiğim gibi, her bir sorgunun dışında denemeliyim. Her bir sorgunun dışında denemeyi denedim, ancak gerçekten sunucuda bir istisna yakalamam. –

İlgili konular