Benjamin
Benjamin

Reputation: 3477

sqlalchemy engine.connect() stalled

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.

Upvotes: 1

Views: 864

Answers (1)

Rach Sharp
Rach Sharp

Reputation: 2454

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

Upvotes: 1

Related Questions