2016-04-26 78 views
3

我目前正在研究一個導入腳本,該腳本從數據庫中導入列表,每隔15分鐘定時關閉一次數據庫以便重新捕獲。Python,重新輸入'with`塊

我創建瞭如下一個with塊創建連接時的重試機制來照顧:

class DBRetryController(object): 
    conn_obj = None 
    connection = None 
    cursor = None 
    retry_count_down = None 
    sleep_time = None 

    def __init__(self, conn_obj, retry_count_down=5, sleep_time=10): 
     self.conn_obj = conn_obj 
     self.retry_count_down = retry_count_down 
     self.sleep_time = sleep_time 

    def __enter__(self): 
     ex = None 
     while self.retry_count_down > 0: 
      try: 
       if hasattr(self.conn_obj, '__call__'): 
        self.connection = self.conn_obj() 
       else: 
        self.connection = self.conn_obj 
       self.cursor = self.connection.cursor() 
       self.retry_count_down = False 
      except OperationalError as ex: 
       log.warning('Caught db error, possibly due to sql server gone away, retrying in a few moment') 
       self.retry_count_down -= 1 
       time.sleep(self.sleep_time) 
     if ex: 
      raise ex 
     return self.connection, self.cursor 

    def __exit__(self, type, value, traceback): 
     try: 
      self.cursor.close() 
      self.connection.close() 
     except: 
      pass 

     if value: 
      raise value 

並如下使用:

with DBRetryController(self.connection) as (_, cursor): 
    cursor.execute(self.LISTING_QUERY) 

但問題是能服務器關閉期間執行查詢,是否可以修改DBRetryController以使嵌套代碼塊重新進入?

+0

_to使嵌套的代碼塊重新enter_。我可以請你再解釋一下,再次進入你的意思是什麼? – EbraHim

+0

基本上從'__enter__'開始重新執行到嵌套塊。 –

+0

你不能在你的程序中定義一個全局計數器,並在'__enter__'方法開始時增加一個,並在其末尾減少1。並在調用'cursor.execute(self.LISTING_QUERY)'後的行中檢查該值是否在程序開始時的值相同(如果不相等,則需要調用方法agian)? – EbraHim

回答

0

如果我正確理解你的問題,我想你可以使用這樣的方案:

notCompleted = 1 
class TestClass(): 
    def run(self): 
     global notCompleted 
     notCompleted = 1 
     #do_something here 
     notCompleted = 0 


test = TestClass() 
test.run() 
while(notCompleted): 
    test.run() 

讓我們假設,我想可以肯定,即使run()方法的執行過程中的任何錯誤occure,我的計劃會重試完成再次運行它。 notCompleted默認爲1。當我在開始時調用run方法時,我將它分配給1,並且在我的run方法結束時,我將0分配給它。如果我有任何問題,在run()的任何位置,在while循環中函數將再次調用。

我想你還需要添加一個Try...Catch

+0

感謝您的嘗試,但這不是我正在尋找的解決方案。 –