1

I use sqlachemy to connect to a remote database but I do not know the type (can be PostgreSQL, MariaDB, etc.). I try them in a loop and I keep the first working driver:

for driver in drivers:
        try:
            uri = get_uri_from_driver(driver)
            engine = create_engine(uri, echo=False)
            print('Try connection')
            con = engine.engine.connect()
            # Try to get some lines
            return engine
        except Exception:
            continue
 return None

In some case the con = engine.engine.connect() does not end and it happens when you try the MySQL driver to connect to something which is not MySQL (Oracle).

Questions:

  1. How can I set a timeout to this?

  2. If I cannot, is there any other way to achieve this ? (I will for example base the test order with the default port but I would like to be able to kill the connect() after some seconds.

EDIT:

This code is in a Django so I cannot use signal/alarm because of multi-threading.

Benjamin
  • 3,350
  • 4
  • 24
  • 49

1 Answers1

1

This can be done with a generic timeout solution like in:

What should I do if socket.setdefaulttimeout() is not working?

import signal

class Timeout():
    """Timeout class using ALARM signal"""
    class TimeoutException(Exception): pass

    def __init__(self, sec):
        self.sec = sec

    def __enter__(self):
        signal.signal(signal.SIGALRM, self.raise_timeout)
        signal.alarm(self.sec)

    def __exit__(self, *args):
        signal.alarm(0) # disable alarm

    def raise_timeout(self, *args):
        raise Timeout.TimeoutException()


# In your example
try:
    uri = get_uri_from_driver(driver)
    engine = create_engine(uri, echo=False)
    print('Try connection')
    with Timeout(10):
        con = engine.engine.connect()
    # Try to get some lines
    return engine
except Exception:
    continue
Rach Sharp
  • 2,324
  • 14
  • 31
  • Does not work with Django (multi-thread): ValueError: signal only works in main thread. I add this to the question – Benjamin Oct 06 '17 at 13:38