From a9288ca5bd979d8aab9921f71bf5b722b1c3ab3d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 9 Aug 2010 20:49:08 -0400 Subject: [PATCH] working with how this will be documented and having some probs with sphinx --- doc/build/reference/orm/index.rst | 2 + doc/build/reference/orm/query.rst | 4 +- doc/build/reference/sqlalchemy/event.rst | 14 +- doc/build/reference/sqlalchemy/index.rst | 2 + doc/build/reference/sqlalchemy/interfaces.rst | 4 +- lib/sqlalchemy/engine/base.py | 94 +++++------ lib/sqlalchemy/event.py | 10 +- lib/sqlalchemy/interfaces.py | 5 +- lib/sqlalchemy/pool.py | 153 +++++++++--------- test/engine/test_pool.py | 8 +- 10 files changed, 161 insertions(+), 135 deletions(-) diff --git a/doc/build/reference/orm/index.rst b/doc/build/reference/orm/index.rst index 001d7b4eeb..e98d5a1117 100644 --- a/doc/build/reference/orm/index.rst +++ b/doc/build/reference/orm/index.rst @@ -3,6 +3,8 @@ sqlalchemy.orm ============== +.. module:: sqlalchemy.orm + .. toctree:: :glob: diff --git a/doc/build/reference/orm/query.rst b/doc/build/reference/orm/query.rst index 931bbf064c..ee30abd4a8 100644 --- a/doc/build/reference/orm/query.rst +++ b/doc/build/reference/orm/query.rst @@ -3,7 +3,9 @@ Querying ======== -.. module:: sqlalchemy.orm +.. module:: sqlalchemy.orm.query + +.. currentmodule:: sqlalchemy.orm The Query Object ---------------- diff --git a/doc/build/reference/sqlalchemy/event.rst b/doc/build/reference/sqlalchemy/event.rst index 05e7ab63b7..ec36ee5990 100644 --- a/doc/build/reference/sqlalchemy/event.rst +++ b/doc/build/reference/sqlalchemy/event.rst @@ -1,7 +1,19 @@ Events ------- +====== .. automodule:: sqlalchemy.event + +.. autofunction:: sqlalchemy.event.listen + +Connection Pool Events +---------------------- + +.. autoclass:: sqlalchemy.pool.PoolEvents :members: +Connection Events +------------------------ + +.. autoclass:: sqlalchemy.engine.base.EngineEvents + :members: diff --git a/doc/build/reference/sqlalchemy/index.rst b/doc/build/reference/sqlalchemy/index.rst index b87c2900bd..0bcc980632 100644 --- a/doc/build/reference/sqlalchemy/index.rst +++ b/doc/build/reference/sqlalchemy/index.rst @@ -1,6 +1,8 @@ sqlalchemy ========== +.. module:: sqlalchemy + .. toctree:: :glob: diff --git a/doc/build/reference/sqlalchemy/interfaces.rst b/doc/build/reference/sqlalchemy/interfaces.rst index 27882b5b27..b1430e2d77 100644 --- a/doc/build/reference/sqlalchemy/interfaces.rst +++ b/doc/build/reference/sqlalchemy/interfaces.rst @@ -1,5 +1,5 @@ -Interfaces ----------- +Interfaces (Deprecated) +------------------------ SQLAlchemy's interface system is now deprecated, and has been superceded by a more flexible and consistent event dispatch diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 4260e923ab..7b6ff5b7a3 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1546,6 +1546,54 @@ class TwoPhaseTransaction(Transaction): def _do_commit(self): self.connection._commit_twophase_impl(self.xid, self._is_prepared) +class EngineEvents(event.Events): + """Available events for :class:`.Engine`.""" + + @classmethod + def listen(cls, fn, identifier, target): + if issubclass(target.Connection, Connection): + target.Connection = _proxy_connection_cls( + Connection, + target.events) + event.Events.listen(fn, identifier, target) + + def on_execute(self, conn, execute, clauseelement, *multiparams, **params): + """Intercept high level execute() events.""" + + def on_cursor_execute(self, conn, execute, cursor, statement, + parameters, context, executemany): + """Intercept low-level cursor execute() events.""" + + def on_begin(self, conn, begin): + """Intercept begin() events.""" + + def on_rollback(self, conn, rollback): + """Intercept rollback() events.""" + + def on_commit(self, conn, commit): + """Intercept commit() events.""" + + def on_savepoint(self, conn, savepoint, name=None): + """Intercept savepoint() events.""" + + def on_rollback_savepoint(self, conn, rollback_savepoint, name, context): + """Intercept rollback_savepoint() events.""" + + def on_release_savepoint(self, conn, release_savepoint, name, context): + """Intercept release_savepoint() events.""" + + def on_begin_twophase(self, conn, begin_twophase, xid): + """Intercept begin_twophase() events.""" + + def on_prepare_twophase(self, conn, prepare_twophase, xid): + """Intercept prepare_twophase() events.""" + + def on_rollback_twophase(self, conn, rollback_twophase, xid, is_prepared): + """Intercept rollback_twophase() events.""" + + def on_commit_twophase(self, conn, commit_twophase, xid, is_prepared): + """Intercept commit_twophase() events.""" + class Engine(Connectable, log.Identified): """ Connects a :class:`~sqlalchemy.pool.Pool` and @@ -1578,52 +1626,8 @@ class Engine(Connectable, log.Identified): if execution_options: self.update_execution_options(**execution_options) - class events(event.Events): - @classmethod - def listen(cls, fn, identifier, target): - if issubclass(target.Connection, Connection): - target.Connection = _proxy_connection_cls( - Connection, - target.events) - event.Events.listen(fn, identifier, target) - def on_execute(self, conn, execute, clauseelement, *multiparams, **params): - """Intercept high level execute() events.""" - - def on_cursor_execute(self, conn, execute, cursor, statement, - parameters, context, executemany): - """Intercept low-level cursor execute() events.""" - - def on_begin(self, conn, begin): - """Intercept begin() events.""" - - def on_rollback(self, conn, rollback): - """Intercept rollback() events.""" - - def on_commit(self, conn, commit): - """Intercept commit() events.""" - - def on_savepoint(self, conn, savepoint, name=None): - """Intercept savepoint() events.""" - - def on_rollback_savepoint(self, conn, rollback_savepoint, name, context): - """Intercept rollback_savepoint() events.""" - - def on_release_savepoint(self, conn, release_savepoint, name, context): - """Intercept release_savepoint() events.""" - - def on_begin_twophase(self, conn, begin_twophase, xid): - """Intercept begin_twophase() events.""" - - def on_prepare_twophase(self, conn, prepare_twophase, xid): - """Intercept prepare_twophase() events.""" - - def on_rollback_twophase(self, conn, rollback_twophase, xid, is_prepared): - """Intercept rollback_twophase() events.""" - - def on_commit_twophase(self, conn, commit_twophase, xid, is_prepared): - """Intercept commit_twophase() events.""" - events = event.dispatcher(events) + events = event.dispatcher(EngineEvents) def update_execution_options(self, **opt): """update the execution_options dictionary of this :class:`Engine`. diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 603aaf383c..5a8c193a02 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -1,10 +1,7 @@ """ -The event system handles all events throughout the sqlalchemy -and sqlalchemy.orm packages. +The event system handles all events throughout the :mod:`sqlalchemy` +and :mod:`sqlalchemy.orm` packages. -Event specifications: - -:attr:`sqlalchemy.pool.Pool.events` """ @@ -110,7 +107,8 @@ class EventDescriptor(object): self._clslevel = util.defaultdict(list) def append(self, obj, target): - assert isinstance(target, type), "Class-level Event targets must be classes." + assert isinstance(target, type), \ + "Class-level Event targets must be classes." for cls in [target] + target.__subclasses__(): self._clslevel[cls].append(obj) diff --git a/lib/sqlalchemy/interfaces.py b/lib/sqlalchemy/interfaces.py index 4eaf4d4ad3..36573bf437 100644 --- a/lib/sqlalchemy/interfaces.py +++ b/lib/sqlalchemy/interfaces.py @@ -14,7 +14,7 @@ class PoolListener(object): .. note:: :class:`PoolListener` is deprecated. Please refer to :func:`event.listen` as well as - :attr:`Pool.events`. + :attr:`.Pool.events`. Usage:: @@ -146,7 +146,8 @@ class ConnectionProxy(object): """Allows interception of statement execution by Connections. .. note:: :class:`ConnectionProxy` is deprecated. Please - refer to :func:`event.listen`. + refer to :func:`event.listen` as well as + :attr:`.Engine.events`. Either or both of the ``execute()`` and ``cursor_execute()`` may be implemented to intercept compiled statement and diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 9574d28da6..8a28455623 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -57,6 +57,82 @@ def clear_managers(): manager.close() proxies.clear() +class PoolEvents(event.Events): + """Available events for :class:`.Pool`. + + The methods here define the name of an event as well + as the names of members that are passed to listener + functions. Note all members are passed by name. + + e.g.:: + + from sqlalchemy import events + + def my_on_checkout(dbapi_conn, connection_rec, connection_proxy): + "handle an on checkout event" + + events.listen(my_on_checkout, 'on_checkout', Pool) + + """ + + def on_connect(self, dbapi_connection, connection_record): + """Called once for each new DB-API connection or Pool's ``creator()``. + + :param dbapi_con: + A newly connected raw DB-API connection (not a SQLAlchemy + ``Connection`` wrapper). + + :param con_record: + The ``_ConnectionRecord`` that persistently manages the connection + + """ + + def on_first_connect(self, dbapi_connection, connection_record): + """Called exactly once for the first DB-API connection. + + :param dbapi_con: + A newly connected raw DB-API connection (not a SQLAlchemy + ``Connection`` wrapper). + + :param con_record: + The ``_ConnectionRecord`` that persistently manages the connection + + """ + + def on_checkout(self, dbapi_connection, connection_record, connection_proxy): + """Called when a connection is retrieved from the Pool. + + :param dbapi_con: + A raw DB-API connection + + :param con_record: + The ``_ConnectionRecord`` that persistently manages the connection + + :param con_proxy: + The ``_ConnectionFairy`` which manages the connection for the span of + the current checkout. + + If you raise an ``exc.DisconnectionError``, the current + connection will be disposed and a fresh connection retrieved. + Processing of all checkout listeners will abort and restart + using the new connection. + """ + + def on_checkin(self, dbapi_connection, connection_record): + """Called when a connection returns to the pool. + + Note that the connection may be closed, and may be None if the + connection has been invalidated. ``checkin`` will not be called + for detached connections. (They do not return to the pool.) + + :param dbapi_con: + A raw DB-API connection + + :param con_record: + The ``_ConnectionRecord`` that persistently manages the connection + + """ + class Pool(log.Identified): """Abstract base class for connection pools.""" @@ -133,82 +209,11 @@ class Pool(log.Identified): for l in listeners: self.add_listener(l) - class events(event.Events): - """Available events for :class:`Pool`. - - The methods here define the name of an event as well - as the names of members that are passed to listener - functions. Note all members are passed by name. - - e.g.:: - - from sqlalchemy import events - events.listen(fn, 'on_checkout', Pool) - - """ - - def on_connect(self, dbapi_connection, connection_record): - """Called once for each new DB-API connection or Pool's ``creator()``. - - :param dbapi_con: - A newly connected raw DB-API connection (not a SQLAlchemy - ``Connection`` wrapper). - - :param con_record: - The ``_ConnectionRecord`` that persistently manages the connection - - """ - - def on_first_connect(self, dbapi_connection, connection_record): - """Called exactly once for the first DB-API connection. - - :param dbapi_con: - A newly connected raw DB-API connection (not a SQLAlchemy - ``Connection`` wrapper). - - :param con_record: - The ``_ConnectionRecord`` that persistently manages the connection - - """ - - def on_checkout(self, dbapi_connection, connection_record, connection_proxy): - """Called when a connection is retrieved from the Pool. - - :param dbapi_con: - A raw DB-API connection - - :param con_record: - The ``_ConnectionRecord`` that persistently manages the connection - - :param con_proxy: - The ``_ConnectionFairy`` which manages the connection for the span of - the current checkout. - - If you raise an ``exc.DisconnectionError``, the current - connection will be disposed and a fresh connection retrieved. - Processing of all checkout listeners will abort and restart - using the new connection. - """ - - def on_checkin(self, dbapi_connection, connection_record): - """Called when a connection returns to the pool. - - Note that the connection may be closed, and may be None if the - connection has been invalidated. ``checkin`` will not be called - for detached connections. (They do not return to the pool.) - - :param dbapi_con: - A raw DB-API connection - - :param con_record: - The ``_ConnectionRecord`` that persistently manages the connection - - """ - events = event.dispatcher(events) + events = event.dispatcher(PoolEvents) - @util.deprecated("Pool.add_listener() is deprecated. Use event.listen()") + @util.deprecated(":meth:`.Pool.add_listener` is deprecated. Use :func:`.event.listen`") def add_listener(self, listener): - """Add a ``PoolListener``-like object to this pool. + """Add a :class:`.PoolListener`-like object to this pool. ``listener`` may be an object that implements some or all of PoolListener, or a dictionary of callables containing implementations diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py index c9cd6bdd44..e09b7a04fe 100644 --- a/test/engine/test_pool.py +++ b/test/engine/test_pool.py @@ -403,13 +403,13 @@ class PoolTest(PoolTestBase): assert_listeners(p, 1, 1, 1, 1) p.add_listener(i_connect) - assert_listeners(p, 2, 2, 1, 1) + assert_listeners(p, 2, 1, 1, 1) p.add_listener(i_checkout) - assert_listeners(p, 3, 2, 2, 1) + assert_listeners(p, 3, 1, 1, 1) p.add_listener(i_checkin) - assert_listeners(p, 4, 2, 2, 2) + assert_listeners(p, 4, 1, 1, 1) del p p = _pool(listeners=[i_all]) @@ -424,7 +424,7 @@ class PoolTest(PoolTestBase): assert counts == [1, 2, 1] p.add_listener(i_checkin) c.close() - assert counts == [1, 2, 3] + assert counts == [1, 2, 2] def test_listener_after_oninit(self): """Test that listeners are called after OnInit is removed""" -- 2.47.3