2016-04-26 5 views
3

Ich arbeite gerade an einem Import-Skript, das Einträge aus einer Datenbank importiert, die regelmäßig alle 15 Minuten zum erneuten Snap heruntergefahren wird.Python, den "with" -Block erneut eingeben

Ich habe erstellt einen with Block wie unten nach dem Wiederholungsmechanismus zu suchen, wenn Verbindungen zu schaffen:

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 

Und wie unten verwenden:

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

Aber das Problem ist der Server herunterfahren kann während Ausführung der Abfrage, ist es möglich, die DBRetryController zu ändern, um den verschachtelten Code-Block erneut eingeben zu machen?

+0

_So machen Sie den verschachtelten Code-Block erneut eingeben_. Darf ich Sie bitten, etwas mehr zu erklären, was meinst du mit _wiedereintreten_? – EbraHim

+0

im Grunde von Anfang an von "__enter__" zum verschachtelten Block erneut auszuführen. –

+0

Kannst du keinen globalen Zähler in deinem Programm definieren und ihn am Anfang der '__enter__' Methode um eins erhöhen und ihn am Ende um 1 verringern. und in der Zeile nach dem Aufruf der 'cursor.execute (self.LISTING_QUERY)' überprüfen Sie den Wert auf den gleichen Wert am Anfang des Programms (wenn die nicht gleich sind, müssen Sie die Methode Agian aufrufen)? – EbraHim

Antwort

0

Wenn ich Ihre Frage richtig verstanden habe, ich glaube, Sie, ein solches System verwenden können:

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


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

Lassen Sie davon ausgehen, dass ich sicher sein wollen, auch wenn ein Fehler während der Ausführung von run() Methode occure, mein Programm wird Versuchen Sie es erneut zu beenden, um es erneut auszuführen. Die notCompleted ist standardmäßig 1. Wenn ich die Methode run am Anfang aufrufen, weise ich ihr 1 zu und am Ende meiner run Methode habe ich ihr 0 zugewiesen. Irgendwo in der run() wenn ich irgendein Problem habe, in der While-Schleife wird die Funktion erneut aufgerufen.

Ich denke, Sie müssen auch eine Try...Catch hinzufügen.

+0

Danke für den Versuch, aber das ist nicht die Lösung, die ich suche. –

Verwandte Themen