summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/engine/base.py4
-rw-r--r--lib/sqlalchemy/interfaces.py363
-rw-r--r--lib/sqlalchemy/orm/__init__.py3
-rw-r--r--lib/sqlalchemy/orm/attributes.py23
-rw-r--r--lib/sqlalchemy/orm/deprecated_interfaces.py572
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py15
-rw-r--r--lib/sqlalchemy/orm/interfaces.py12
-rw-r--r--lib/sqlalchemy/orm/mapper.py54
-rw-r--r--lib/sqlalchemy/orm/properties.py15
-rw-r--r--lib/sqlalchemy/orm/relationships.py16
-rw-r--r--lib/sqlalchemy/orm/session.py20
-rw-r--r--lib/sqlalchemy/orm/strategies.py3
-rw-r--r--lib/sqlalchemy/pool/base.py35
13 files changed, 6 insertions, 1129 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index a0a2680ca..27da8c295 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -14,7 +14,6 @@ from .interfaces import ExceptionContext
from .util import _distill_params
from .. import exc
from .. import inspection
-from .. import interfaces
from .. import log
from .. import util
from ..sql import schema
@@ -1910,7 +1909,6 @@ class Engine(Connectable, log.Identified):
url,
logging_name=None,
echo=None,
- proxy=None,
execution_options=None,
hide_parameters=False,
):
@@ -1922,8 +1920,6 @@ class Engine(Connectable, log.Identified):
self.echo = echo
self.hide_parameters = hide_parameters
log.instance_logger(self, echoflag=echo)
- if proxy:
- interfaces.ConnectionProxy._adapt_listener(self, proxy)
if execution_options:
self.update_execution_options(**execution_options)
diff --git a/lib/sqlalchemy/interfaces.py b/lib/sqlalchemy/interfaces.py
deleted file mode 100644
index 374199143..000000000
--- a/lib/sqlalchemy/interfaces.py
+++ /dev/null
@@ -1,363 +0,0 @@
-# sqlalchemy/interfaces.py
-# Copyright (C) 2007-2019 the SQLAlchemy authors and contributors
-# <see AUTHORS file>
-# Copyright (C) 2007 Jason Kirtland jek@discorporate.us
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-"""Deprecated core event interfaces.
-
-
-.. deprecated:: 0.7
- As of SQLAlchemy 0.7, the new event system described in
- :ref:`event_toplevel` replaces the extension/proxy/listener system,
- providing a consistent interface to all events without the need for
- subclassing.
-
-"""
-
-from . import event
-from . import util
-
-
-class PoolListener(object):
- """Hooks into the lifecycle of connections in a :class:`.Pool`.
-
- .. deprecated:: 0.7
-
- :class:`.PoolListener` is deprecated and will be removed in a future
- release. Please refer to :func:`.event.listen` in conjunction with
- the :class:`.PoolEvents` listener interface.
-
- Usage::
-
- class MyListener(PoolListener):
- def connect(self, dbapi_con, con_record):
- '''perform connect operations'''
- # etc.
-
- # create a new pool with a listener
- p = QueuePool(..., listeners=[MyListener()])
-
- # add a listener after the fact
- p.add_listener(MyListener())
-
- # usage with create_engine()
- e = create_engine("url://", listeners=[MyListener()])
-
- All of the standard connection :class:`~sqlalchemy.pool.Pool` types can
- accept event listeners for key connection lifecycle events:
- creation, pool check-out and check-in. There are no events fired
- when a connection closes.
-
- For any given DB-API connection, there will be one ``connect``
- event, `n` number of ``checkout`` events, and either `n` or `n - 1`
- ``checkin`` events. (If a ``Connection`` is detached from its
- pool via the ``detach()`` method, it won't be checked back in.)
-
- These are low-level events for low-level objects: raw Python
- DB-API connections, without the conveniences of the SQLAlchemy
- ``Connection`` wrapper, ``Dialect`` services or ``ClauseElement``
- execution. If you execute SQL through the connection, explicitly
- closing all cursors and other resources is recommended.
-
- Events also receive a ``_ConnectionRecord``, a long-lived internal
- ``Pool`` object that basically represents a "slot" in the
- connection pool. ``_ConnectionRecord`` objects have one public
- attribute of note: ``info``, a dictionary whose contents are
- scoped to the lifetime of the DB-API connection managed by the
- record. You can use this shared storage area however you like.
-
- There is no need to subclass ``PoolListener`` to handle events.
- Any class that implements one or more of these methods can be used
- as a pool listener. The ``Pool`` will inspect the methods
- provided by a listener object and add the listener to one or more
- internal event queues based on its capabilities. In terms of
- efficiency and function call overhead, you're much better off only
- providing implementations for the hooks you'll be using.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- """Adapt a :class:`.PoolListener` to individual
- :class:`event.Dispatch` events.
-
- """
-
- methods = ["connect", "first_connect", "checkout", "checkin"]
- listener = util.as_interface(listener, methods=methods)
-
- for meth in methods:
- me_meth = getattr(PoolListener, meth)
- ls_meth = getattr(listener, meth, None)
-
- if ls_meth is not None and not util.methods_equivalent(
- me_meth, ls_meth
- ):
- util.warn_deprecated(
- "PoolListener.%s is deprecated. The "
- "PoolListener class will be removed in a future "
- "release. Please transition to the @event interface, "
- "using @event.listens_for(Engine, '%s')." % (meth, meth)
- )
-
- if hasattr(listener, "connect"):
- event.listen(self, "connect", listener.connect)
- if hasattr(listener, "first_connect"):
- event.listen(self, "first_connect", listener.first_connect)
- if hasattr(listener, "checkout"):
- event.listen(self, "checkout", listener.checkout)
- if hasattr(listener, "checkin"):
- event.listen(self, "checkin", listener.checkin)
-
- def connect(self, dbapi_con, con_record):
- """Called once for each new DB-API connection or Pool's ``creator()``.
-
- dbapi_con
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def first_connect(self, dbapi_con, con_record):
- """Called exactly once for the first DB-API connection.
-
- dbapi_con
- A newly connected raw DB-API connection (not a SQLAlchemy
- ``Connection`` wrapper).
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
- def checkout(self, dbapi_con, con_record, con_proxy):
- """Called when a connection is retrieved from the Pool.
-
- dbapi_con
- A raw DB-API connection
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- 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 checkin(self, dbapi_con, con_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.)
-
- dbapi_con
- A raw DB-API connection
-
- con_record
- The ``_ConnectionRecord`` that persistently manages the connection
-
- """
-
-
-class ConnectionProxy(object):
- """Allows interception of statement execution by Connections.
-
- .. deprecated:: 0.7
-
- :class:`.ConnectionProxy` is deprecated and will be removed in a future
- release. Please refer to :func:`.event.listen` in conjunction with
- the :class:`.ConnectionEvents` listener interface.
-
- Either or both of the ``execute()`` and ``cursor_execute()``
- may be implemented to intercept compiled statement and
- cursor level executions, e.g.::
-
- class MyProxy(ConnectionProxy):
- def execute(self, conn, execute, clauseelement,
- *multiparams, **params):
- print "compiled statement:", clauseelement
- return execute(clauseelement, *multiparams, **params)
-
- def cursor_execute(self, execute, cursor, statement,
- parameters, context, executemany):
- print "raw statement:", statement
- return execute(cursor, statement, parameters, context)
-
- The ``execute`` argument is a function that will fulfill the default
- execution behavior for the operation. The signature illustrated
- in the example should be used.
-
- The proxy is installed into an :class:`~sqlalchemy.engine.Engine` via
- the ``proxy`` argument::
-
- e = create_engine('someurl://', proxy=MyProxy())
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
-
- methods = [
- "execute",
- "cursor_execute",
- "begin",
- "rollback",
- "commit",
- "savepoint",
- "rollback_savepoint",
- "release_savepoint",
- "begin_twophase",
- "prepare_twophase",
- "rollback_twophase",
- "commit_twophase",
- ]
- for meth in methods:
- me_meth = getattr(ConnectionProxy, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- util.warn_deprecated(
- "ConnectionProxy.%s is deprecated. The "
- "ConnectionProxy class will be removed in a future "
- "release. Please transition to the @event interface, "
- "using @event.listens_for(Engine, '%s')." % (meth, meth)
- )
-
- def adapt_execute(conn, clauseelement, multiparams, params):
- def execute_wrapper(clauseelement, *multiparams, **params):
- return clauseelement, multiparams, params
-
- return listener.execute(
- conn, execute_wrapper, clauseelement, *multiparams, **params
- )
-
- event.listen(self, "before_execute", adapt_execute)
-
- def adapt_cursor_execute(
- conn, cursor, statement, parameters, context, executemany
- ):
- def execute_wrapper(cursor, statement, parameters, context):
- return statement, parameters
-
- return listener.cursor_execute(
- execute_wrapper,
- cursor,
- statement,
- parameters,
- context,
- executemany,
- )
-
- event.listen(self, "before_cursor_execute", adapt_cursor_execute)
-
- def do_nothing_callback(*arg, **kw):
- pass
-
- def adapt_listener(fn):
- def go(conn, *arg, **kw):
- fn(conn, do_nothing_callback, *arg, **kw)
-
- return util.update_wrapper(go, fn)
-
- event.listen(self, "begin", adapt_listener(listener.begin))
- event.listen(self, "rollback", adapt_listener(listener.rollback))
- event.listen(self, "commit", adapt_listener(listener.commit))
- event.listen(self, "savepoint", adapt_listener(listener.savepoint))
- event.listen(
- self,
- "rollback_savepoint",
- adapt_listener(listener.rollback_savepoint),
- )
- event.listen(
- self,
- "release_savepoint",
- adapt_listener(listener.release_savepoint),
- )
- event.listen(
- self, "begin_twophase", adapt_listener(listener.begin_twophase)
- )
- event.listen(
- self, "prepare_twophase", adapt_listener(listener.prepare_twophase)
- )
- event.listen(
- self,
- "rollback_twophase",
- adapt_listener(listener.rollback_twophase),
- )
- event.listen(
- self, "commit_twophase", adapt_listener(listener.commit_twophase)
- )
-
- def execute(self, conn, execute, clauseelement, *multiparams, **params):
- """Intercept high level execute() events."""
-
- return execute(clauseelement, *multiparams, **params)
-
- def cursor_execute(
- self, execute, cursor, statement, parameters, context, executemany
- ):
- """Intercept low-level cursor execute() events."""
-
- return execute(cursor, statement, parameters, context)
-
- def begin(self, conn, begin):
- """Intercept begin() events."""
-
- return begin()
-
- def rollback(self, conn, rollback):
- """Intercept rollback() events."""
-
- return rollback()
-
- def commit(self, conn, commit):
- """Intercept commit() events."""
-
- return commit()
-
- def savepoint(self, conn, savepoint, name=None):
- """Intercept savepoint() events."""
-
- return savepoint(name=name)
-
- def rollback_savepoint(self, conn, rollback_savepoint, name, context):
- """Intercept rollback_savepoint() events."""
-
- return rollback_savepoint(name, context)
-
- def release_savepoint(self, conn, release_savepoint, name, context):
- """Intercept release_savepoint() events."""
-
- return release_savepoint(name, context)
-
- def begin_twophase(self, conn, begin_twophase, xid):
- """Intercept begin_twophase() events."""
-
- return begin_twophase(xid)
-
- def prepare_twophase(self, conn, prepare_twophase, xid):
- """Intercept prepare_twophase() events."""
-
- return prepare_twophase(xid)
-
- def rollback_twophase(self, conn, rollback_twophase, xid, is_prepared):
- """Intercept rollback_twophase() events."""
-
- return rollback_twophase(xid, is_prepared)
-
- def commit_twophase(self, conn, commit_twophase, xid, is_prepared):
- """Intercept commit_twophase() events."""
-
- return commit_twophase(xid, is_prepared)
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index a596d1408..8bd68b417 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -16,9 +16,6 @@ documentation for an overview of how this module is used.
from . import exc # noqa
from . import mapper as mapperlib # noqa
from . import strategy_options
-from .deprecated_interfaces import AttributeExtension # noqa
-from .deprecated_interfaces import MapperExtension # noqa
-from .deprecated_interfaces import SessionExtension # noqa
from .descriptor_props import ComparableProperty # noqa
from .descriptor_props import CompositeProperty # noqa
from .descriptor_props import SynonymProperty # noqa
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index 117dd4cea..1466f5f47 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -465,7 +465,6 @@ class AttributeImpl(object):
callable_,
dispatch,
trackparent=False,
- extension=None,
compare_function=None,
active_history=False,
parent_token=None,
@@ -490,19 +489,6 @@ class AttributeImpl(object):
if True, attempt to track if an instance has a parent attached
to it via this attribute.
- :param extension:
- a single or list of AttributeExtension object(s) which will
- receive set/delete/append/remove/etc. events.
- The event package is now used.
-
- .. deprecated:: 1.3
-
- The :paramref:`.AttributeImpl.extension` parameter is deprecated
- and will be removed in a future release, corresponding to the
- "extension" parameter on the :class:`.MapperProprty` classes
- like :func:`.column_property` and :func:`.relationship` The
- events system is now used.
-
:param compare_function:
a function that compares two values which are normally
assignable to this attribute.
@@ -545,13 +531,6 @@ class AttributeImpl(object):
else:
self.accepts_scalar_loader = self.default_accepts_scalar_loader
- # TODO: pass in the manager here
- # instead of doing a lookup
- attr = manager_of_class(class_)[key]
-
- for ext in util.to_list(extension or []):
- ext._adapt_listener(attr, ext)
-
if active_history:
self.dispatch._active_history = True
@@ -1075,7 +1054,6 @@ class CollectionAttributeImpl(AttributeImpl):
dispatch,
typecallable=None,
trackparent=False,
- extension=None,
copy_function=None,
compare_function=None,
**kwargs
@@ -1086,7 +1064,6 @@ class CollectionAttributeImpl(AttributeImpl):
callable_,
dispatch,
trackparent=trackparent,
- extension=extension,
compare_function=compare_function,
**kwargs
)
diff --git a/lib/sqlalchemy/orm/deprecated_interfaces.py b/lib/sqlalchemy/orm/deprecated_interfaces.py
deleted file mode 100644
index 4069b43a5..000000000
--- a/lib/sqlalchemy/orm/deprecated_interfaces.py
+++ /dev/null
@@ -1,572 +0,0 @@
-# orm/deprecated_interfaces.py
-# Copyright (C) 2005-2019 the SQLAlchemy authors and contributors
-# <see AUTHORS file>
-#
-# This module is part of SQLAlchemy and is released under
-# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-from .interfaces import EXT_CONTINUE
-from .. import event
-from .. import util
-
-
-@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces")
-class MapperExtension(object):
- """Base implementation for :class:`.Mapper` event hooks.
-
- .. deprecated:: 0.7
-
- :class:`.MapperExtension` is deprecated and will be removed in a future
- release. Please refer to :func:`.event.listen` in conjunction with
- the :class:`.MapperEvents` listener interface.
-
- New extension classes subclass :class:`.MapperExtension` and are specified
- using the ``extension`` mapper() argument, which is a single
- :class:`.MapperExtension` or a list of such::
-
- from sqlalchemy.orm.interfaces import MapperExtension
-
- class MyExtension(MapperExtension):
- def before_insert(self, mapper, connection, instance):
- print "instance %s before insert !" % instance
-
- m = mapper(User, users_table, extension=MyExtension())
-
- A single mapper can maintain a chain of ``MapperExtension``
- objects. When a particular mapping event occurs, the
- corresponding method on each ``MapperExtension`` is invoked
- serially, and each method has the ability to halt the chain
- from proceeding further::
-
- m = mapper(User, users_table, extension=[ext1, ext2, ext3])
-
- Each ``MapperExtension`` method returns the symbol
- EXT_CONTINUE by default. This symbol generally means "move
- to the next ``MapperExtension`` for processing". For methods
- that return objects like translated rows or new object
- instances, EXT_CONTINUE means the result of the method
- should be ignored. In some cases it's required for a
- default mapper activity to be performed, such as adding a
- new instance to a result list.
-
- The symbol EXT_STOP has significance within a chain
- of ``MapperExtension`` objects that the chain will be stopped
- when this symbol is returned. Like EXT_CONTINUE, it also
- has additional significance in some cases that a default
- mapper activity will not be performed.
-
- """
-
- @classmethod
- def _adapt_instrument_class(cls, self, listener):
- cls._adapt_listener_methods(self, listener, ("instrument_class",))
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- cls._adapt_listener_methods(
- self,
- listener,
- (
- "init_instance",
- "init_failed",
- "reconstruct_instance",
- "before_insert",
- "after_insert",
- "before_update",
- "after_update",
- "before_delete",
- "after_delete",
- ),
- )
-
- @classmethod
- def _adapt_listener_methods(cls, self, listener, methods):
-
- for meth in methods:
- me_meth = getattr(MapperExtension, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- util.warn_deprecated(
- "MapperExtension.%s is deprecated. The "
- "MapperExtension class will be removed in a future "
- "release. Please transition to the @event interface, "
- "using @event.listens_for(mapped_class, '%s')."
- % (meth, meth)
- )
-
- if meth == "reconstruct_instance":
-
- def go(ls_meth):
- def reconstruct(instance, ctx):
- ls_meth(self, instance)
-
- return reconstruct
-
- event.listen(
- self.class_manager,
- "load",
- go(ls_meth),
- raw=False,
- propagate=True,
- )
- elif meth == "init_instance":
-
- def go(ls_meth):
- def init_instance(instance, args, kwargs):
- ls_meth(
- self,
- self.class_,
- self.class_manager.original_init,
- instance,
- args,
- kwargs,
- )
-
- return init_instance
-
- event.listen(
- self.class_manager,
- "init",
- go(ls_meth),
- raw=False,
- propagate=True,
- )
- elif meth == "init_failed":
-
- def go(ls_meth):
- def init_failed(instance, args, kwargs):
- util.warn_exception(
- ls_meth,
- self,
- self.class_,
- self.class_manager.original_init,
- instance,
- args,
- kwargs,
- )
-
- return init_failed
-
- event.listen(
- self.class_manager,
- "init_failure",
- go(ls_meth),
- raw=False,
- propagate=True,
- )
- else:
- event.listen(
- self,
- "%s" % meth,
- ls_meth,
- raw=False,
- retval=True,
- propagate=True,
- )
-
- def instrument_class(self, mapper, class_):
- """Receive a class when the mapper is first constructed, and has
- applied instrumentation to the mapped class.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def init_instance(self, mapper, class_, oldinit, instance, args, kwargs):
- """Receive an instance when its constructor is called.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def init_failed(self, mapper, class_, oldinit, instance, args, kwargs):
- """Receive an instance when its constructor has been called,
- and raised an exception.
-
- This method is only called during a userland construction of
- an object. It is not called when an object is loaded from the
- database.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def reconstruct_instance(self, mapper, instance):
- """Receive an object instance after it has been created via
- ``__new__``, and after initial attribute population has
- occurred.
-
- This typically occurs when the instance is created based on
- incoming result rows, and is only called once for that
- instance's lifetime.
-
- Note that during a result-row load, this method is called upon
- the first row received for this instance. Note that some
- attributes and collections may or may not be loaded or even
- initialized, depending on what's present in the result rows.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
- return EXT_CONTINUE
-
- def before_insert(self, mapper, connection, instance):
- """Receive an object instance before that instance is inserted
- into its table.
-
- This is a good place to set up primary key values and such
- that aren't handled otherwise.
-
- Column-based attributes can be modified within this method
- which will result in the new value being inserted. However
- *no* changes to the overall flush plan can be made, and
- manipulation of the ``Session`` will not have the desired effect.
- To manipulate the ``Session`` within an extension, use
- ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_insert(self, mapper, connection, instance):
- """Receive an object instance after that instance is inserted.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def before_update(self, mapper, connection, instance):
- """Receive an object instance before that instance is updated.
-
- Note that this method is called for all instances that are marked as
- "dirty", even those which have no net changes to their column-based
- attributes. An object is marked as dirty when any of its column-based
- attributes have a "set attribute" operation called or when any of its
- collections are modified. If, at update time, no column-based
- attributes have any net changes, no UPDATE statement will be issued.
- This means that an instance being sent to before_update is *not* a
- guarantee that an UPDATE statement will be issued (although you can
- affect the outcome here).
-
- To detect if the column-based attributes on the object have net
- changes, and will therefore generate an UPDATE statement, use
- ``object_session(instance).is_modified(instance,
- include_collections=False)``.
-
- Column-based attributes can be modified within this method
- which will result in the new value being updated. However
- *no* changes to the overall flush plan can be made, and
- manipulation of the ``Session`` will not have the desired effect.
- To manipulate the ``Session`` within an extension, use
- ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_update(self, mapper, connection, instance):
- """Receive an object instance after that instance is updated.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def before_delete(self, mapper, connection, instance):
- """Receive an object instance before that instance is deleted.
-
- Note that *no* changes to the overall flush plan can be made
- here; and manipulation of the ``Session`` will not have the
- desired effect. To manipulate the ``Session`` within an
- extension, use ``SessionExtension``.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
- def after_delete(self, mapper, connection, instance):
- """Receive an object instance after that instance is deleted.
-
- The return value is only significant within the ``MapperExtension``
- chain; the parent mapper's behavior isn't modified by this method.
-
- """
-
- return EXT_CONTINUE
-
-
-@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces")
-class SessionExtension(object):
-
- """Base implementation for :class:`.Session` event hooks.
-
- .. deprecated:: 0.7
-
- :class:`.SessionExtension` is deprecated and will be removed in a future
- release. Please refer to :func:`.event.listen` in conjunction with
- the :class:`.SessionEvents` listener interface.
-
- Subclasses may be installed into a :class:`.Session` (or
- :class:`.sessionmaker`) using the ``extension`` keyword
- argument::
-
- from sqlalchemy.orm.interfaces import SessionExtension
-
- class MySessionExtension(SessionExtension):
- def before_commit(self, session):
- print "before commit!"
-
- Session = sessionmaker(extension=MySessionExtension())
-
- The same :class:`.SessionExtension` instance can be used
- with any number of sessions.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- for meth in [
- "before_commit",
- "after_commit",
- "after_rollback",
- "before_flush",
- "after_flush",
- "after_flush_postexec",
- "after_begin",
- "after_attach",
- "after_bulk_update",
- "after_bulk_delete",
- ]:
- me_meth = getattr(SessionExtension, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- util.warn_deprecated(
- "SessionExtension.%s is deprecated. The "
- "SessionExtension class will be removed in a future "
- "release. Please transition to the @event interface, "
- "using @event.listens_for(Session, '%s')." % (meth, meth)
- )
-
- event.listen(self, meth, getattr(listener, meth))
-
- def before_commit(self, session):
- """Execute right before commit is called.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_commit(self, session):
- """Execute after a commit has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def after_rollback(self, session):
- """Execute after a rollback has occurred.
-
- Note that this may not be per-flush if a longer running
- transaction is ongoing."""
-
- def before_flush(self, session, flush_context, instances):
- """Execute before flush process has started.
-
- `instances` is an optional list of objects which were passed to
- the ``flush()`` method. """
-
- def after_flush(self, session, flush_context):
- """Execute after flush has completed, but before commit has been
- called.
-
- Note that the session's state is still in pre-flush, i.e. 'new',
- 'dirty', and 'deleted' lists still show pre-flush state as well
- as the history settings on instance attributes."""
-
- def after_flush_postexec(self, session, flush_context):
- """Execute after flush has completed, and after the post-exec
- state occurs.
-
- This will be when the 'new', 'dirty', and 'deleted' lists are in
- their final state. An actual commit() may or may not have
- occurred, depending on whether or not the flush started its own
- transaction or participated in a larger transaction. """
-
- def after_begin(self, session, transaction, connection):
- """Execute after a transaction is begun on a connection
-
- `transaction` is the SessionTransaction. This method is called
- after an engine level transaction is begun on a connection. """
-
- def after_attach(self, session, instance):
- """Execute after an instance is attached to a session.
-
- This is called after an add, delete or merge. """
-
- def after_bulk_update(self, session, query, query_context, result):
- """Execute after a bulk update operation to the session.
-
- This is called after a session.query(...).update()
-
- `query` is the query object that this update operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
- def after_bulk_delete(self, session, query, query_context, result):
- """Execute after a bulk delete operation to the session.
-
- This is called after a session.query(...).delete()
-
- `query` is the query object that this delete operation was
- called on. `query_context` was the query context object.
- `result` is the result object returned from the bulk operation.
- """
-
-
-@util.langhelpers.dependency_for("sqlalchemy.orm.interfaces")
-class AttributeExtension(object):
- """Base implementation for :class:`.AttributeImpl` event hooks, events
- that fire upon attribute mutations in user code.
-
- .. deprecated:: 0.7
-
- :class:`.AttributeExtension` is deprecated and will be removed in a
- future release. Please refer to :func:`.event.listen` in conjunction
- with the :class:`.AttributeEvents` listener interface.
-
- :class:`.AttributeExtension` is used to listen for set,
- remove, and append events on individual mapped attributes.
- It is established on an individual mapped attribute using
- the `extension` argument, available on
- :func:`.column_property`, :func:`.relationship`, and
- others::
-
- from sqlalchemy.orm.interfaces import AttributeExtension
- from sqlalchemy.orm import mapper, relationship, column_property
-
- class MyAttrExt(AttributeExtension):
- def append(self, state, value, initiator):
- print "append event !"
- return value
-
- def set(self, state, value, oldvalue, initiator):
- print "set event !"
- return value
-
- mapper(SomeClass, sometable, properties={
- 'foo':column_property(sometable.c.foo, extension=MyAttrExt()),
- 'bar':relationship(Bar, extension=MyAttrExt())
- })
-
- Note that the :class:`.AttributeExtension` methods
- :meth:`~.AttributeExtension.append` and
- :meth:`~.AttributeExtension.set` need to return the
- ``value`` parameter. The returned value is used as the
- effective value, and allows the extension to change what is
- ultimately persisted.
-
- AttributeExtension is assembled within the descriptors associated
- with a mapped class.
-
- """
-
- active_history = True
- """indicates that the set() method would like to receive the 'old' value,
- even if it means firing lazy callables.
-
- Note that ``active_history`` can also be set directly via
- :func:`.column_property` and :func:`.relationship`.
-
- """
-
- @classmethod
- def _adapt_listener(cls, self, listener):
- for meth in ["append", "remove", "set"]:
- me_meth = getattr(AttributeExtension, meth)
- ls_meth = getattr(listener, meth)
-
- if not util.methods_equivalent(me_meth, ls_meth):
- util.warn_deprecated(
- "AttributeExtension.%s is deprecated. The "
- "AttributeExtension class will be removed in a future "
- "release. Please transition to the @event interface, "
- "using @event.listens_for(Class.attribute, '%s')."
- % (meth, meth)
- )
-
- event.listen(
- self,
- "append",
- listener.append,
- active_history=listener.active_history,
- raw=True,
- retval=True,
- )
- event.listen(
- self,
- "remove",
- listener.remove,
- active_history=listener.active_history,
- raw=True,
- retval=True,
- )
- event.listen(
- self,
- "set",
- listener.set,
- active_history=listener.active_history,
- raw=True,
- retval=True,
- )
-
- def append(self, state, value, initiator):
- """Receive a collection append event.
-
- The returned value will be used as the actual value to be
- appended.
-
- """
- return value
-
- def remove(self, state, value, initiator):
- """Receive a remove event.
-
- No return value is defined.
-
- """
- pass
-
- def set(self, state, value, oldvalue, initiator):
- """Receive a set event.
-
- The returned value will be used as the actual value to be
- set.
-
- """
- return value
diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py
index 075638fed..dd482bf06 100644
--- a/lib/sqlalchemy/orm/descriptor_props.py
+++ b/lib/sqlalchemy/orm/descriptor_props.py
@@ -97,15 +97,6 @@ class CompositeProperty(DescriptorProperty):
"""
- @util.deprecated_params(
- extension=(
- "0.7",
- ":class:`.AttributeExtension` is deprecated in favor of the "
- ":class:`.AttributeEvents` listener interface. The "
- ":paramref:`.composite.extension` parameter will be "
- "removed in a future release.",
- )
- )
def __init__(self, class_, *attrs, **kwargs):
r"""Return a composite column-based property for use with a Mapper.
@@ -148,12 +139,6 @@ class CompositeProperty(DescriptorProperty):
:param info: Optional data dictionary which will be populated into the
:attr:`.MapperProperty.info` attribute of this object.
- :param extension:
- an :class:`.AttributeExtension` instance,
- or list of extensions, which will be prepended to the list of
- attribute listeners for the resulting descriptor placed on the
- class.
-
"""
super(CompositeProperty, self).__init__()
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index d6bdfb924..09d1858b9 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -9,11 +9,9 @@
Contains various base classes used throughout the ORM.
-Defines some key base classes prominent within the internals,
-as well as the now-deprecated ORM extension classes.
+Defines some key base classes prominent within the internals.
-Other than the deprecated extensions, this module and the
-classes within are mostly private, though some attributes
+This module and the classes within are mostly private, though some attributes
are exposed when inspecting mappings.
"""
@@ -40,11 +38,7 @@ from .. import util
from ..sql import operators
-# imported later
-MapperExtension = SessionExtension = AttributeExtension = None
-
__all__ = (
- "AttributeExtension",
"EXT_CONTINUE",
"EXT_STOP",
"EXT_SKIP",
@@ -53,11 +47,9 @@ __all__ = (
"MANYTOONE",
"NOT_EXTENSION",
"LoaderStrategy",
- "MapperExtension",
"MapperOption",
"MapperProperty",
"PropComparator",
- "SessionExtension",
"StrategizedProperty",
)
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index e8b215653..0d8d454eb 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -108,13 +108,6 @@ class Mapper(InspectionAttr):
_dispose_called = False
@util.deprecated_params(
- extension=(
- "0.7",
- ":class:`.MapperExtension` is deprecated in favor of the "
- ":class:`.MapperEvents` listener interface. The "
- ":paramref:`.mapper.extension` parameter will be "
- "removed in a future release.",
- ),
order_by=(
"1.1",
"The :paramref:`.mapper.order_by` parameter "
@@ -141,7 +134,6 @@ class Mapper(InspectionAttr):
inherits=None,
inherit_condition=None,
inherit_foreign_keys=None,
- extension=None,
order_by=False,
always_refresh=False,
version_id_col=None,
@@ -295,10 +287,6 @@ class Mapper(InspectionAttr):
See :ref:`include_exclude_cols` for an example.
- :param extension: A :class:`.MapperExtension` instance or
- list of :class:`.MapperExtension` instances which will be applied
- to all operations by this :class:`.Mapper`.
-
:param include_properties: An inclusive list or set of string column
names to map.
@@ -673,7 +661,6 @@ class Mapper(InspectionAttr):
self._memoized_values = {}
self._compiled_cache_size = _compiled_cache_size
self._reconstructor = None
- self._deprecated_extensions = util.to_list(extension or [])
self.allow_partial_pks = allow_partial_pks
if self.inherits and not self.concrete:
@@ -715,9 +702,7 @@ class Mapper(InspectionAttr):
try:
self.dispatch._events._new_mapper_instance(class_, self)
self._configure_inheritance()
- self._configure_legacy_instrument_class()
self._configure_class_instrumentation()
- self._configure_listeners()
self._configure_properties()
self._configure_polymorphic_setter()
self._configure_pks()
@@ -1012,6 +997,9 @@ class Mapper(InspectionAttr):
"Class '%s' does not inherit from '%s'"
% (self.class_.__name__, self.inherits.class_.__name__)
)
+
+ self.dispatch._update(self.inherits.dispatch)
+
if self.non_primary != self.inherits.non_primary:
np = not self.non_primary and "primary" or "non-primary"
raise sa_exc.ArgumentError(
@@ -1206,42 +1194,6 @@ class Mapper(InspectionAttr):
self.polymorphic_on = polymorphic_on
self._configure_polymorphic_setter(True)
- def _configure_legacy_instrument_class(self):
-
- if self.inherits:
- self.dispatch._update(self.inherits.dispatch)
- super_extensions = set(
- chain(
- *[
- m._deprecated_extensions
- for m in self.inherits.iterate_to_root()
- ]
- )
- )
- else:
- super_extensions = set()
-
- for ext in self._deprecated_extensions:
- if ext not in super_extensions:
- ext._adapt_instrument_class(self, ext)
-
- def _configure_listeners(self):
- if self.inherits:
- super_extensions = set(
- chain(
- *[
- m._deprecated_extensions
- for m in self.inherits.iterate_to_root()
- ]
- )
- )
- else:
- super_extensions = set()
-
- for ext in self._deprecated_extensions:
- if ext not in super_extensions:
- ext._adapt_listener(self, ext)
-
def _configure_class_instrumentation(self):
"""If this mapper is to be a primary mapper (i.e. the
non_primary flag is not set), associate this Mapper with the
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index f804d6eed..f8bf06926 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -44,7 +44,6 @@ class ColumnProperty(StrategizedProperty):
"instrument",
"comparator_factory",
"descriptor",
- "extension",
"active_history",
"expire_on_flush",
"info",
@@ -56,15 +55,6 @@ class ColumnProperty(StrategizedProperty):
"_deferred_column_loader",
)
- @util.deprecated_params(
- extension=(
- "0.7",
- ":class:`.AttributeExtension` is deprecated in favor of the "
- ":class:`.AttributeEvents` listener interface. The "
- ":paramref:`.column_property.extension` parameter will be "
- "removed in a future release.",
- )
- )
def __init__(self, *columns, **kwargs):
r"""Provide a column-level property for use with a Mapper.
@@ -125,10 +115,6 @@ class ColumnProperty(StrategizedProperty):
:param info: Optional data dictionary which will be populated into the
:attr:`.MapperProperty.info` attribute of this object.
- :param extension:
- an :class:`.AttributeExtension` instance, or list of extensions,
- which will be prepended to the list of attribute listeners for the
- resulting descriptor placed on the class.
"""
super(ColumnProperty, self).__init__()
@@ -148,7 +134,6 @@ class ColumnProperty(StrategizedProperty):
"comparator_factory", self.__class__.Comparator
)
self.descriptor = kwargs.pop("descriptor", None)
- self.extension = kwargs.pop("extension", None)
self.active_history = kwargs.pop("active_history", False)
self.expire_on_flush = kwargs.pop("expire_on_flush", True)
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py
index 731947cba..a8013f36d 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -107,15 +107,6 @@ class RelationshipProperty(StrategizedProperty):
_dependency_processor = None
- @util.deprecated_params(
- extension=(
- "0.7",
- ":class:`.AttributeExtension` is deprecated in favor of the "
- ":class:`.AttributeEvents` listener interface. The "
- ":paramref:`.relationship.extension` parameter will be "
- "removed in a future release.",
- )
- )
def __init__(
self,
argument,
@@ -129,7 +120,6 @@ class RelationshipProperty(StrategizedProperty):
back_populates=None,
post_update=False,
cascade=False,
- extension=None,
viewonly=False,
lazy="select",
collection_class=None,
@@ -415,11 +405,6 @@ class RelationshipProperty(StrategizedProperty):
:param doc:
docstring which will be applied to the resulting descriptor.
- :param extension:
- an :class:`.AttributeExtension` instance, or list of extensions,
- which will be prepended to the list of attribute listeners for
- the resulting descriptor placed on the class.
-
:param foreign_keys:
a list of columns which are to be used as "foreign key"
@@ -865,7 +850,6 @@ class RelationshipProperty(StrategizedProperty):
self.join_depth = join_depth
self.omit_join = omit_join
self.local_remote_pairs = _local_remote_pairs
- self.extension = extension
self.bake_queries = bake_queries
self.load_on_pending = load_on_pending
self.comparator_factory = (
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index 3aa392ecf..5cf31da0f 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -25,7 +25,6 @@ from .base import instance_str
from .base import object_mapper
from .base import object_state
from .base import state_str
-from .deprecated_interfaces import SessionExtension
from .unitofwork import UOWTransaction
from .. import engine
from .. import exc as sa_exc
@@ -37,7 +36,7 @@ from ..sql import roles
from ..sql import util as sql_util
-__all__ = ["Session", "SessionTransaction", "SessionExtension", "sessionmaker"]
+__all__ = ["Session", "SessionTransaction", "sessionmaker"]
_sessions = weakref.WeakValueDictionary()
"""Weak-referencing dictionary of :class:`.Session` objects.
@@ -660,13 +659,6 @@ class Session(_SessionClassMethods):
"The :paramref:`.Session._enable_transaction_accounting` "
"parameter is deprecated and will be removed in a future release.",
),
- extension=(
- "0.7",
- ":class:`.SessionExtension` is deprecated in favor of the "
- ":class:`.SessionEvents` listener interface. The "
- ":paramref:`.Session.extension` parameter will be "
- "removed in a future release.",
- ),
)
def __init__(
self,
@@ -678,7 +670,6 @@ class Session(_SessionClassMethods):
twophase=False,
weak_identity_map=None,
binds=None,
- extension=None,
enable_baked_queries=True,
info=None,
query_cls=None,
@@ -789,11 +780,6 @@ class Session(_SessionClassMethods):
so that all attribute/object access subsequent to a completed
transaction will load from the most recent database state.
- :param extension: An optional
- :class:`~.SessionExtension` instance, or a list
- of such instances, which will receive pre- and post- commit and
- flush events, as well as a post-rollback event.
-
:param info: optional dictionary of arbitrary data to be associated
with this :class:`.Session`. Is available via the
:attr:`.Session.info` attribute. Note the dictionary is copied at
@@ -850,10 +836,6 @@ class Session(_SessionClassMethods):
if info:
self.info.update(info)
- if extension:
- for ext in util.to_list(extension):
- SessionExtension._adapt_listener(self, ext)
-
if binds is not None:
for key, bind in binds.items():
self._add_bind(key, bind)
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index f82973b39..f82fc2c57 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -51,8 +51,6 @@ def _register_attribute(
**kw
):
- attribute_ext = list(util.to_list(prop.extension, default=[]))
-
listen_hooks = []
uselist = useobject and prop.uselist
@@ -105,7 +103,6 @@ def _register_attribute(
uselist=uselist,
compare_function=compare_function,
useobject=useobject,
- extension=attribute_ext,
trackparent=useobject
and (
prop.single_parent
diff --git a/lib/sqlalchemy/pool/base.py b/lib/sqlalchemy/pool/base.py
index c45f836db..db1197eec 100644
--- a/lib/sqlalchemy/pool/base.py
+++ b/lib/sqlalchemy/pool/base.py
@@ -16,7 +16,6 @@ import weakref
from .. import event
from .. import exc
-from .. import interfaces
from .. import log
from .. import util
from ..util import threading
@@ -60,15 +59,6 @@ class Pool(log.Identified):
_dialect = _ConnDialect()
- @util.deprecated_params(
- listeners=(
- "0.7",
- ":class:`.PoolListener` is deprecated in favor of the "
- ":class:`.PoolEvents` listener interface. The "
- ":paramref:`.Pool.listeners` parameter will be removed in a "
- "future release.",
- )
- )
def __init__(
self,
creator,
@@ -76,7 +66,6 @@ class Pool(log.Identified):
echo=None,
logging_name=None,
reset_on_return=True,
- listeners=None,
events=None,
dialect=None,
pre_ping=False,
@@ -155,11 +144,6 @@ class Pool(log.Identified):
can be assigned via :func:`.create_engine` before dialect-level
listeners are applied.
- :param listeners: A list of :class:`.PoolListener`-like objects or
- dictionaries of callables that receive events when DB-API
- connections are created, checked out and checked in to the
- pool.
-
:param dialect: a :class:`.Dialect` that will handle the job
of calling rollback(), close(), or commit() on DBAPI connections.
If omitted, a built-in "stub" dialect is used. Applications that
@@ -211,9 +195,6 @@ class Pool(log.Identified):
if events:
for fn, target in events:
event.listen(self, target, fn)
- if listeners:
- for l in listeners:
- self.add_listener(l)
@property
def _creator(self):
@@ -260,22 +241,6 @@ class Pool(log.Identified):
"Exception closing connection %r", connection, exc_info=True
)
- @util.deprecated(
- "0.7",
- "The :meth:`.Pool.add_listener` method is deprecated and "
- "will be removed in a future release. Please use the "
- ":class:`.PoolEvents` listener interface.",
- )
- def add_listener(self, listener):
- """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
- of some or all of the named methods in PoolListener.
-
- """
- interfaces.PoolListener._adapt_listener(self, listener)
-
def _create_connection(self):
"""Called by subclasses to create a new ConnectionRecord."""