add before_connect event

Issue #3355 resolved
Mike Bayer repo owner created an issue

this event is to serve use cases that need to affect how the initial connection is created, without the burden of needing to provide the full-blown "creator" callable from scratch (or monkeypatch after the fact).

def before_connect(connect, connect_arg, connect_kwarg, connection_record):
    # 1. we can manipulate the args:
    # connect_kwarg['foo'] = 'bar'

    # 2. we can do things before the connection happens, time delays, etc.
    log.debug("about to connect to db: %s" % connect_arg)

    # 3. we can do the connect ourselves, if we use retval=True
    new_conn = connect(*connect_arg, **connect_kwarg)
    new_conn.do_something()
    return new_conn

The above "connect" is actually going to be dialect.connect. It would be nice if the connection pool were built to work at the level of connect + args, but at the moment it isn't, and explicit use of "creator" is widespread, so this is necessarily an engine-level event.

Additionally it has to either preclude a system that actually passes "creator" to create_engine(), or work such that connect_arg and connect_kwarg are forced to empty, since user-defined creators don't accept or interact with the connect arguments.

For the case where a custom pool is fully provided, we probably need to skip that case for now as well.

We also should, in DefaultEngineStrategy, set up a flag so that when the event is added, and the event can't be added because "pool" was provided or "creator" was provided and we aren't covering that, we can raise an error that the event can't be used in this mode.

The instrumentation would take place within DefaultEngineStrategy, but also has to be ready for an event added to an Engine after the fact; it needs to check that the event can be used at all and ensure it is called if so, else raise an error.

This can be a 1.0.xx feature. Targeting at 1.1 for priority.

Comments (5)

  1. Mike Bayer reporter
    • Added new event :class:.DialectEvents.do_connect, which allows interception / replacement of when the :meth:.Dialect.connect hook is called to create a DBAPI connection. Also added dialect plugin hooks :meth:.Dialect.get_dialect_cls and :meth:.Dialect.engine_created which allow external plugins to add events to existing dialects using entry points. fixes #3355

    → <<cset d2037c31a371>>

  2. Mike Bayer reporter
    • New features added to support engine/pool plugins with advanced functionality. Added a new "soft invalidate" feature to the connection pool at the level of the checked out connection wrapper as well as the :class:._ConnectionRecord. This works similarly to a modern pool invalidation in that connections aren't actively closed, but are recycled only on next checkout; this is essentially a per-connection version of that feature. A new event :class:.PoolEvents.soft_invalidate is added to complement it. fixes #3379

    • Added new flag :attr:.ExceptionContext.invalidate_pool_on_disconnect. Allows an error handler within :meth:.ConnectionEvents.handle_error to maintain a "disconnect" condition, but to handle calling invalidate on individual connections in a specific manner within the event.

    • Added new event :class:.DialectEvents.do_connect, which allows interception / replacement of when the :meth:.Dialect.connect hook is called to create a DBAPI connection. Also added dialect plugin hooks :meth:.Dialect.get_dialect_cls and :meth:.Dialect.engine_created which allow external plugins to add events to existing dialects using entry points. fixes #3355

    → <<cset 0e98795ff2c7>>

  3. Log in to comment