3

I'm looking for the most pythonic way of trying a command, catching if an error occurs and retrying by running a preparatory command and then the original command. Specifically in my case I'm looking to write a table to a database, catch if a "schema does not exist" error is thrown, then trying to create a schema and retrying the write table. Then, if the write table errors again I don't want to catch it.

So far I have (schematically):

try:
    write_to_table(table, schema)
except sqlalchemy.exc.ProgrammingError:
    create_schema(schema)
    write_to_table(table, schema)

This does what I want, but seems a bit off somehow, maybe because I'm duplicating write_to_table().

So what's the most pythonic way of doing the above?

P.S. When I say I'd like to retry, I do NOT want something like this: How to retry after exception?

1 Answers1

0

Just create a reusable decorator !!

def retry(func):
        '''
        Decorator.
        If the decorated function fails with an exception 
        calls it again after a random interval.
        '''
        def _retry(*args,**kwargs):
            max_retries = 1
            for i in range(max_retries):
                try:
                    value = func(*args,**kwargs)
                    return value
                except sqlalchemy.exc.ProgrammingError as e:
                    print('function:[{}({},{})] Failed with error: {} . Retrying...'.format(func.__name__,str(*args),str(kwargs),str(e)))
                    time.sleep(random.uniform(1,3))
            print("Max_retries({}) exceeded for function {}".format(max_retries,func.__name__))
        return _retry

By using the above decorator, in which you can also configure the number of retriesand the retry interval, you can do the following:

@retry
write_to_table(table, schema)