339
def reset(self, dbapi_con, con_record):
340
"""Called before the "reset" action occurs for a pooled connection.
342
This event represents
343
when the ``rollback()`` method is called on the DBAPI connection
344
before it is returned to the pool. The behavior of "reset" can
345
be controlled, including disabled, using the ``reset_on_return``
349
The :meth:`.PoolEvents.reset` event is usually followed by the
350
the :meth:`.PoolEvents.checkin` event is called, except in those
351
cases where the connection is discarded immediately after reset.
354
A raw DB-API connection
357
The ``_ConnectionRecord`` that persistently manages the connection
359
.. versionadded:: 0.8
363
:meth:`.ConnectionEvents.rollback`
365
:meth:`.ConnectionEvents.commit`
336
371
class ConnectionEvents(event.Events):
337
"""Available events for :class:`.Connection`.
339
The methods here define the name of an event as well as the names of members that are passed to listener functions.
372
"""Available events for :class:`.Connectable`, which includes
373
:class:`.Connection` and :class:`.Engine`.
375
The methods here define the name of an event as well as the names of
376
members that are passed to listener functions.
378
An event listener can be associated with any :class:`.Connectable`
379
class or instance, such as an :class:`.Engine`, e.g.::
343
381
from sqlalchemy import event, create_engine
345
def before_execute(conn, clauseelement, multiparams, params):
346
log.info("Received statement: %s" % clauseelement)
383
def before_cursor_execute(conn, cursor, statement, parameters, context,
385
log.info("Received statement: %s" % statement)
348
387
engine = create_engine('postgresql://scott:tiger@localhost/test')
349
event.listen(engine, "before_execute", before_execute)
351
Some events allow modifiers to the listen() function.
388
event.listen(engine, "before_cursor_execute", before_cursor_execute)
390
or with a specific :class:`.Connection`::
392
with engine.begin() as conn:
393
@event.listens_for(conn, 'before_cursor_execute')
394
def before_cursor_execute(conn, cursor, statement, parameters,
395
context, executemany):
396
log.info("Received statement: %s" % statement)
398
The :meth:`.before_execute` and :meth:`.before_cursor_execute`
399
events can also be established with the ``retval=True`` flag, which
400
allows modification of the statement and parameters to be sent
401
to the database. The :meth:`.before_cursor_execute` event is
402
particularly useful here to add ad-hoc string transformations, such
403
as comments, to all executions::
405
from sqlalchemy.engine import Engine
406
from sqlalchemy import event
408
@event.listens_for(Engine, "before_cursor_execute", retval=True)
409
def comment_sql_calls(conn, cursor, statement, parameters,
410
context, executemany):
411
statement = statement + " -- some comment"
412
return statement, parameters
414
.. note:: :class:`.ConnectionEvents` can be established on any
415
combination of :class:`.Engine`, :class:`.Connection`, as well
416
as instances of each of those classes. Events across all
417
four scopes will fire off for a given instance of
418
:class:`.Connection`. However, for performance reasons, the
419
:class:`.Connection` object determines at instantiation time
420
whether or not its parent :class:`.Engine` has event listeners
421
established. Event listeners added to the :class:`.Engine`
422
class or to an instance of :class:`.Engine` *after* the instantiation
423
of a dependent :class:`.Connection` instance will usually
424
*not* be available on that :class:`.Connection` instance. The newly
425
added listeners will instead take effect for :class:`.Connection`
426
instances created subsequent to those event listeners being
427
established on the parent :class:`.Engine` class or instance.
353
429
:param retval=False: Applies to the :meth:`.before_execute` and
354
430
:meth:`.before_cursor_execute` events only. When True, the
367
447
if identifier == 'before_execute':
369
def wrap(conn, clauseelement, multiparams, params):
450
def wrap_before_execute(conn, clauseelement,
451
multiparams, params):
370
452
orig_fn(conn, clauseelement, multiparams, params)
371
453
return clauseelement, multiparams, params
454
fn = wrap_before_execute
373
455
elif identifier == 'before_cursor_execute':
375
def wrap(conn, cursor, statement,
458
def wrap_before_cursor_execute(conn, cursor, statement,
376
459
parameters, context, executemany):
377
460
orig_fn(conn, cursor, statement,
378
461
parameters, context, executemany)
379
462
return statement, parameters
463
fn = wrap_before_cursor_execute
382
elif retval and identifier not in ('before_execute', 'before_cursor_execute'):
466
identifier not in ('before_execute', 'before_cursor_execute'):
383
467
raise exc.ArgumentError(
384
468
"Only the 'before_execute' and "
385
469
"'before_cursor_execute' engine "
388
472
event.Events._listen(target, identifier, fn)
390
474
def before_execute(self, conn, clauseelement, multiparams, params):
391
"""Intercept high level execute() events."""
475
"""Intercept high level execute() events, receiving uncompiled
476
SQL constructs and other objects prior to rendering into SQL.
478
This event is good for debugging SQL compilation issues as well
479
as early manipulation of the parameters being sent to the database,
480
as the parameter lists will be in a consistent format here.
482
This event can be optionally established with the ``retval=True``
483
flag. The ``clauseelement``, ``multiparams``, and ``params``
484
arguments should be returned as a three-tuple in this case::
486
@event.listens_for(Engine, "before_execute", retval=True)
487
def before_execute(conn, conn, clauseelement, multiparams, params):
488
# do something with clauseelement, multiparams, params
489
return clauseelement, multiparams, params
491
:param conn: :class:`.Connection` object
492
:param clauseelement: SQL expression construct, :class:`.Compiled`
493
instance, or string statement passed to :meth:`.Connection.execute`.
494
:param multiparams: Multiple parameter sets, a list of dictionaries.
495
:param params: Single parameter set, a single dictionary.
499
:meth:`.before_cursor_execute`
393
503
def after_execute(self, conn, clauseelement, multiparams, params, result):
394
"""Intercept high level execute() events."""
504
"""Intercept high level execute() events after execute.
507
:param conn: :class:`.Connection` object
508
:param clauseelement: SQL expression construct, :class:`.Compiled`
509
instance, or string statement passed to :meth:`.Connection.execute`.
510
:param multiparams: Multiple parameter sets, a list of dictionaries.
511
:param params: Single parameter set, a single dictionary.
512
:param result: :class:`.ResultProxy` generated by the execution.
396
516
def before_cursor_execute(self, conn, cursor, statement,
397
517
parameters, context, executemany):
398
"""Intercept low-level cursor execute() events."""
518
"""Intercept low-level cursor execute() events before execution,
520
SQL statement and DBAPI-specific parameter list to be invoked
523
This event is a good choice for logging as well as late modifications
524
to the SQL string. It's less ideal for parameter modifications except
525
for those which are specific to a target backend.
527
This event can be optionally established with the ``retval=True``
528
flag. The ``statement`` and ``parameters`` arguments should be
529
returned as a two-tuple in this case::
531
@event.listens_for(Engine, "before_cursor_execute", retval=True)
532
def before_cursor_execute(conn, cursor, statement,
533
parameters, context, executemany):
534
# do something with statement, parameters
535
return statement, parameters
537
See the example at :class:`.ConnectionEvents`.
539
:param conn: :class:`.Connection` object
540
:param cursor: DBAPI cursor object
541
:param statement: string SQL statement
542
:param parameters: Dictionary, tuple, or list of parameters being
543
passed to the ``execute()`` or ``executemany()`` method of the
544
DBAPI ``cursor``. In some cases may be ``None``.
545
:param context: :class:`.ExecutionContext` object in use. May
547
:param executemany: boolean, if ``True``, this is an ``executemany()``
548
call, if ``False``, this is an ``execute()`` call.
552
:meth:`.before_execute`
554
:meth:`.after_cursor_execute`
400
558
def after_cursor_execute(self, conn, cursor, statement,
401
559
parameters, context, executemany):
402
"""Intercept low-level cursor execute() events."""
560
"""Intercept low-level cursor execute() events after execution.
562
:param conn: :class:`.Connection` object
563
:param cursor: DBAPI cursor object. Will have results pending
564
if the statement was a SELECT, but these should not be consumed
565
as they will be needed by the :class:`.ResultProxy`.
566
:param statement: string SQL statement
567
:param parameters: Dictionary, tuple, or list of parameters being
568
passed to the ``execute()`` or ``executemany()`` method of the
569
DBAPI ``cursor``. In some cases may be ``None``.
570
:param context: :class:`.ExecutionContext` object in use. May
572
:param executemany: boolean, if ``True``, this is an ``executemany()``
573
call, if ``False``, this is an ``execute()`` call.
404
577
def dbapi_error(self, conn, cursor, statement, parameters,
405
578
context, exception):
427
600
exception is then wrapped in a SQLAlchemy DBAPI exception
428
601
wrapper and re-thrown.
603
:param conn: :class:`.Connection` object
604
:param cursor: DBAPI cursor object
605
:param statement: string SQL statement
606
:param parameters: Dictionary, tuple, or list of parameters being
607
passed to the ``execute()`` or ``executemany()`` method of the
608
DBAPI ``cursor``. In some cases may be ``None``.
609
:param context: :class:`.ExecutionContext` object in use. May
611
:param exception: The **unwrapped** exception emitted directly from the
612
DBAPI. The class here is specific to the DBAPI module in use.
430
614
.. versionadded:: 0.7.7
434
618
def begin(self, conn):
435
"""Intercept begin() events."""
619
"""Intercept begin() events.
621
:param conn: :class:`.Connection` object
437
625
def rollback(self, conn):
438
"""Intercept rollback() events."""
626
"""Intercept rollback() events, as initiated by a
627
:class:`.Transaction`.
629
Note that the :class:`.Pool` also "auto-rolls back"
630
a DBAPI connection upon checkin, if the ``reset_on_return``
631
flag is set to its default value of ``'rollback'``.
633
rollback, use the :meth:`.PoolEvents.reset` hook.
635
:param conn: :class:`.Connection` object
639
:meth:`.PoolEvents.reset`
440
643
def commit(self, conn):
441
"""Intercept commit() events."""
644
"""Intercept commit() events, as initiated by a
645
:class:`.Transaction`.
647
Note that the :class:`.Pool` may also "auto-commit"
648
a DBAPI connection upon checkin, if the ``reset_on_return``
649
flag is set to the value ``'commit'``. To intercept this
650
commit, use the :meth:`.PoolEvents.reset` hook.
652
:param conn: :class:`.Connection` object
443
655
def savepoint(self, conn, name=None):
444
"""Intercept savepoint() events."""
656
"""Intercept savepoint() events.
658
:param conn: :class:`.Connection` object
659
:param name: specified name used for the savepoint.
446
663
def rollback_savepoint(self, conn, name, context):
447
"""Intercept rollback_savepoint() events."""
664
"""Intercept rollback_savepoint() events.
666
:param conn: :class:`.Connection` object
667
:param name: specified name used for the savepoint.
668
:param context: :class:`.ExecutionContext` in use. May be ``None``.
449
672
def release_savepoint(self, conn, name, context):
450
"""Intercept release_savepoint() events."""
673
"""Intercept release_savepoint() events.
675
:param conn: :class:`.Connection` object
676
:param name: specified name used for the savepoint.
677
:param context: :class:`.ExecutionContext` in use. May be ``None``.
452
681
def begin_twophase(self, conn, xid):
453
"""Intercept begin_twophase() events."""
682
"""Intercept begin_twophase() events.
684
:param conn: :class:`.Connection` object
685
:param xid: two-phase XID identifier
455
689
def prepare_twophase(self, conn, xid):
456
"""Intercept prepare_twophase() events."""
690
"""Intercept prepare_twophase() events.
692
:param conn: :class:`.Connection` object
693
:param xid: two-phase XID identifier
458
696
def rollback_twophase(self, conn, xid, is_prepared):
459
"""Intercept rollback_twophase() events."""
697
"""Intercept rollback_twophase() events.
699
:param conn: :class:`.Connection` object
700
:param xid: two-phase XID identifier
701
:param is_prepared: boolean, indicates if
702
:meth:`.TwoPhaseTransaction.prepare` was called.
461
706
def commit_twophase(self, conn, xid, is_prepared):
462
"""Intercept commit_twophase() events."""
707
"""Intercept commit_twophase() events.
709
:param conn: :class:`.Connection` object
710
:param xid: two-phase XID identifier
711
:param is_prepared: boolean, indicates if
712
:meth:`.TwoPhaseTransaction.prepare` was called.