summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/ext/selectresults.py2
-rw-r--r--lib/sqlalchemy/ext/sessioncontext.py6
-rw-r--r--lib/sqlalchemy/orm/__init__.py24
-rw-r--r--lib/sqlalchemy/orm/interfaces.py89
-rw-r--r--lib/sqlalchemy/orm/mapper.py16
-rw-r--r--lib/sqlalchemy/orm/query.py10
-rw-r--r--lib/sqlalchemy/orm/util.py6
7 files changed, 86 insertions, 67 deletions
diff --git a/lib/sqlalchemy/ext/selectresults.py b/lib/sqlalchemy/ext/selectresults.py
index 1920b6f92..446228254 100644
--- a/lib/sqlalchemy/ext/selectresults.py
+++ b/lib/sqlalchemy/ext/selectresults.py
@@ -15,7 +15,7 @@ class SelectResultsExt(orm.MapperExtension):
def select(self, query, arg=None, **kwargs):
if isinstance(arg, sql.FromClause) and arg.supports_execution():
- return orm.EXT_PASS
+ return orm.EXT_CONTINUE
else:
if arg is not None:
query = query.filter(arg)
diff --git a/lib/sqlalchemy/ext/sessioncontext.py b/lib/sqlalchemy/ext/sessioncontext.py
index fcbf29c3f..91c03d3c3 100644
--- a/lib/sqlalchemy/ext/sessioncontext.py
+++ b/lib/sqlalchemy/ext/sessioncontext.py
@@ -1,5 +1,5 @@
from sqlalchemy.util import ScopedRegistry
-from sqlalchemy.orm import create_session, object_session, MapperExtension, EXT_PASS
+from sqlalchemy.orm import create_session, object_session, MapperExtension, EXT_CONTINUE
__all__ = ['SessionContext', 'SessionContextExt']
@@ -66,11 +66,11 @@ class SessionContextExt(MapperExtension):
def init_instance(self, mapper, class_, instance, args, kwargs):
session = kwargs.pop('_sa_session', self.context.current)
session._save_impl(instance, entity_name=kwargs.pop('_sa_entity_name', None))
- return EXT_PASS
+ return EXT_CONTINUE
def init_failed(self, mapper, class_, instance, args, kwargs):
object_session(instance).expunge(instance)
- return EXT_PASS
+ return EXT_CONTINUE
def dispose_class(self, mapper, class_):
if hasattr(class_, '__init__') and hasattr(class_.__init__, '_oldinit'):
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index 66c4d796e..3c221bb66 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -5,14 +5,15 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
"""
-The mapper package provides object-relational functionality, building upon the schema and sql
-packages and tying operations to class properties and constructors.
+The mapper package provides object-relational functionality, building upon
+the schema and sql packages and tying operations to class properties and
+constructors.
"""
from sqlalchemy import exceptions
from sqlalchemy import util as sautil
from sqlalchemy.orm.mapper import Mapper, object_mapper, class_mapper, mapper_registry
-from sqlalchemy.orm.interfaces import SynonymProperty, MapperExtension, EXT_PASS, ExtensionOption, PropComparator
+from sqlalchemy.orm.interfaces import SynonymProperty, MapperExtension, EXT_CONTINUE, EXT_STOP, EXT_PASS, ExtensionOption, PropComparator
from sqlalchemy.orm.properties import PropertyLoader, ColumnProperty, CompositeProperty, BackRef
from sqlalchemy.orm import mapper as mapperlib
from sqlalchemy.orm import collections, strategies
@@ -21,14 +22,15 @@ from sqlalchemy.orm.util import polymorphic_union
from sqlalchemy.orm.session import Session as _Session
from sqlalchemy.orm.session import object_session, attribute_manager
-__all__ = ['relation', 'column_property', 'composite', 'backref', 'eagerload',
- 'eagerload_all', 'lazyload', 'noload', 'deferred', 'defer', 'undefer',
- 'undefer_group', 'extension', 'mapper', 'clear_mappers',
- 'compile_mappers', 'class_mapper', 'object_mapper', 'dynamic_loader',
- 'MapperExtension', 'Query', 'polymorphic_union', 'create_session','Session',
- 'synonym', 'contains_alias', 'contains_eager', 'EXT_PASS',
- 'object_session', 'PropComparator'
- ]
+__all__ = [ 'relation', 'column_property', 'composite', 'backref', 'eagerload',
+ 'eagerload_all', 'lazyload', 'noload', 'deferred', 'defer',
+ 'undefer', 'undefer_group', 'extension', 'mapper', 'clear_mappers',
+ 'compile_mappers', 'class_mapper', 'object_mapper',
+ 'dynamic_loader', 'MapperExtension', 'Query', 'polymorphic_union',
+ 'create_session', 'Session', 'synonym', 'contains_alias',
+ 'contains_eager', 'EXT_CONTINUE', 'EXT_STOP', 'EXT_PASS',
+ 'object_session', 'PropComparator' ]
+
def create_session(bind=None, **kwargs):
"""create a new version 0.3-style [sqlalchemy.orm.session#Session].
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index eba8384c6..271846ca8 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -7,22 +7,39 @@
from sqlalchemy import util, logging, sql
-# returned by a MapperExtension method to indicate a "do nothing" response
-EXT_PASS = object()
+__all__ = ['EXT_CONTINUE', 'EXT_STOP', 'EXT_PASS', 'MapperExtension',
+ 'MapperProperty', 'PropComparator', 'StrategizedProperty',
+ 'LoaderStack', 'OperationContext', 'MapperOption',
+ 'ExtensionOption', 'SynonymProperty', 'PropertyOption',
+ 'AttributeExtension', 'StrategizedOption', 'LoaderStrategy' ]
+
+EXT_CONTINUE = EXT_PASS = object()
+EXT_STOP = object()
class MapperExtension(object):
- """Base implementation for an object that provides overriding
- behavior to various Mapper functions. For each method in
- MapperExtension, a result of EXT_PASS indicates the functionality
- is not overridden.
+ """Base implementation for customizing Mapper behavior.
+
+ For each method in MapperExtension, returning a result of
+ EXT_CONTINUE will allow processing to continue to the next
+ MapperExtension in line or use the default functionality if there
+ are no other extensions.
+
+ Returning EXT_STOP will halt processing of further extensions
+ handling that method. Some methods such as ``load`` have other
+ return requirements, see the individual documentation for details.
+ Other than these exception cases, any return value other than
+ EXT_CONTINUE or EXT_STOP will be interpreted as equivalent to
+ EXT_STOP.
+
+ EXT_PASS is a synonym for EXT_CONTINUE and is provided for
+ backward compatibility.
"""
-
def init_instance(self, mapper, class_, instance, args, kwargs):
- return EXT_PASS
+ return EXT_CONTINUE
def init_failed(self, mapper, class_, instance, args, kwargs):
- return EXT_PASS
+ return EXT_CONTINUE
def get_session(self):
"""Retrieve a contextual Session instance with which to
@@ -32,61 +49,61 @@ class MapperExtension(object):
`__init__` params (i.e. `_sa_session`).
"""
- return EXT_PASS
+ return EXT_CONTINUE
def load(self, query, *args, **kwargs):
"""Override the `load` method of the Query object.
The return value of this method is used as the result of
- ``query.load()`` if the value is anything other than EXT_PASS.
+ ``query.load()`` if the value is anything other than EXT_CONTINUE.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def get(self, query, *args, **kwargs):
"""Override the `get` method of the Query object.
The return value of this method is used as the result of
- ``query.get()`` if the value is anything other than EXT_PASS.
+ ``query.get()`` if the value is anything other than EXT_CONTINUE.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def get_by(self, query, *args, **kwargs):
"""Override the `get_by` method of the Query object.
The return value of this method is used as the result of
``query.get_by()`` if the value is anything other than
- EXT_PASS.
+ EXT_CONTINUE.
DEPRECATED.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def select_by(self, query, *args, **kwargs):
"""Override the `select_by` method of the Query object.
The return value of this method is used as the result of
``query.select_by()`` if the value is anything other than
- EXT_PASS.
+ EXT_CONTINUE.
DEPRECATED.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def select(self, query, *args, **kwargs):
"""Override the `select` method of the Query object.
The return value of this method is used as the result of
``query.select()`` if the value is anything other than
- EXT_PASS.
+ EXT_CONTINUE.
DEPRECATED.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def translate_row(self, mapper, context, row):
@@ -97,7 +114,7 @@ class MapperExtension(object):
method.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def create_instance(self, mapper, selectcontext, row, class_):
"""Receive a row when a new object instance is about to be
@@ -120,13 +137,13 @@ class MapperExtension(object):
The class we are mapping.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def append_result(self, mapper, selectcontext, row, instance, result, **flags):
"""Receive an object instance before that instance is appended
to a result list.
- If this method returns EXT_PASS, result appending will proceed
+ If this method returns EXT_CONTINUE, result appending will proceed
normally. if this method returns any other value or None,
result appending will not proceed for this instance, giving
this extension an opportunity to do the appending itself, if
@@ -152,7 +169,7 @@ class MapperExtension(object):
`create_row_processor()` method of [sqlalchemy.orm.interfaces#MapperProperty]
"""
- return EXT_PASS
+ return EXT_CONTINUE
def populate_instance(self, mapper, selectcontext, row, instance, **flags):
"""Receive a newly-created instance before that instance has
@@ -161,14 +178,14 @@ class MapperExtension(object):
The normal population of attributes is according to each
attribute's corresponding MapperProperty (which includes
column-based attributes as well as relationships to other
- classes). If this method returns EXT_PASS, instance
+ classes). If this method returns EXT_CONTINUE, instance
population will proceed normally. If any other value or None
is returned, instance population will not proceed, giving this
extension an opportunity to populate the instance itself, if
desired.
"""
- return EXT_PASS
+ return EXT_CONTINUE
def before_insert(self, mapper, connection, instance):
"""Receive an object instance before that instance is INSERTed
@@ -178,32 +195,32 @@ class MapperExtension(object):
that aren't handled otherwise.
"""
- return EXT_PASS
+ return EXT_CONTINUE
+
+ def after_insert(self, mapper, connection, instance):
+ """Receive an object instance after that instance is INSERTed."""
+
+ return EXT_CONTINUE
def before_update(self, mapper, connection, instance):
"""Receive an object instance before that instance is UPDATEed."""
- return EXT_PASS
+ return EXT_CONTINUE
def after_update(self, mapper, connection, instance):
"""Receive an object instance after that instance is UPDATEed."""
- return EXT_PASS
-
- def after_insert(self, mapper, connection, instance):
- """Receive an object instance after that instance is INSERTed."""
-
- return EXT_PASS
+ return EXT_CONTINUE
def before_delete(self, mapper, connection, instance):
"""Receive an object instance before that instance is DELETEed."""
- return EXT_PASS
+ return EXT_CONTINUE
def after_delete(self, mapper, connection, instance):
"""Receive an object instance after that instance is DELETEed."""
- return EXT_PASS
+ return EXT_CONTINUE
class MapperProperty(object):
"""Manage the relationship of a ``Mapper`` to a single class
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 6706b07e4..3560a1c59 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -9,7 +9,7 @@ from sqlalchemy import sql_util as sqlutil
from sqlalchemy.orm import util as mapperutil
from sqlalchemy.orm.util import ExtensionCarrier
from sqlalchemy.orm import sync
-from sqlalchemy.orm.interfaces import MapperProperty, EXT_PASS, MapperExtension, SynonymProperty
+from sqlalchemy.orm.interfaces import MapperProperty, EXT_CONTINUE, MapperExtension, SynonymProperty
import weakref, warnings, operator
__all__ = ['Mapper', 'class_mapper', 'object_mapper', 'mapper_registry']
@@ -876,7 +876,7 @@ class Mapper(object):
self.compile()
s = self.extension.get_session()
- if s is EXT_PASS:
+ if s is EXT_CONTINUE:
raise exceptions.InvalidRequestError("No contextual Session is established. Use a MapperExtension that implements get_session or use 'import sqlalchemy.mods.threadlocal' to establish a default thread-local contextual session.")
return s
@@ -1373,7 +1373,7 @@ class Mapper(object):
extension = self.extension
ret = extension.translate_row(self, context, row)
- if ret is not EXT_PASS:
+ if ret is not EXT_CONTINUE:
row = ret
if not skip_polymorphic and self.polymorphic_on is not None:
@@ -1404,9 +1404,9 @@ class Mapper(object):
if not context.identity_map.has_key(identitykey):
context.identity_map[identitykey] = instance
isnew = True
- if extension.populate_instance(self, context, row, instance, **{'instancekey':identitykey, 'isnew':isnew}) is EXT_PASS:
+ if extension.populate_instance(self, context, row, instance, **{'instancekey':identitykey, 'isnew':isnew}) is EXT_CONTINUE:
self.populate_instance(context, instance, row, **{'instancekey':identitykey, 'isnew':isnew})
- if extension.append_result(self, context, row, instance, result, **{'instancekey':identitykey, 'isnew':isnew}) is EXT_PASS:
+ if extension.append_result(self, context, row, instance, result, **{'instancekey':identitykey, 'isnew':isnew}) is EXT_CONTINUE:
if result is not None:
result.append(instance)
return instance
@@ -1432,7 +1432,7 @@ class Mapper(object):
# plugin point
instance = extension.create_instance(self, context, row, self.class_)
- if instance is EXT_PASS:
+ if instance is EXT_CONTINUE:
instance = self._create_instance(context.session)
else:
instance._entity_name = self.entity_name
@@ -1447,9 +1447,9 @@ class Mapper(object):
# call further mapper properties on the row, to pull further
# instances from the row and possibly populate this item.
flags = {'instancekey':identitykey, 'isnew':isnew}
- if extension.populate_instance(self, context, row, instance, **flags) is EXT_PASS:
+ if extension.populate_instance(self, context, row, instance, **flags) is EXT_CONTINUE:
self.populate_instance(context, instance, row, **flags)
- if extension.append_result(self, context, row, instance, result, **flags) is EXT_PASS:
+ if extension.append_result(self, context, row, instance, result, **flags) is EXT_CONTINUE:
if result is not None:
result.append(instance)
return instance
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 1b5871858..6d7e55af3 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -70,7 +70,7 @@ class Query(object):
"""
ret = self._extension.get(self, ident, **kwargs)
- if ret is not mapper.EXT_PASS:
+ if ret is not mapper.EXT_CONTINUE:
return ret
# convert composite types to individual args
@@ -94,7 +94,7 @@ class Query(object):
"""
ret = self._extension.load(self, ident, **kwargs)
- if ret is not mapper.EXT_PASS:
+ if ret is not mapper.EXT_CONTINUE:
return ret
key = self.mapper.identity_key_from_primary_key(ident)
instance = self._get(key, ident, reload=True, **kwargs)
@@ -993,7 +993,7 @@ class Query(object):
"""DEPRECATED. use query.filter_by(\**params).first()"""
ret = self._extension.get_by(self, *args, **params)
- if ret is not mapper.EXT_PASS:
+ if ret is not mapper.EXT_CONTINUE:
return ret
return self._legacy_filter_by(*args, **params).first()
@@ -1002,7 +1002,7 @@ class Query(object):
"""DEPRECATED. use use query.filter_by(\**params).all()."""
ret = self._extension.select_by(self, *args, **params)
- if ret is not mapper.EXT_PASS:
+ if ret is not mapper.EXT_CONTINUE:
return ret
return self._legacy_filter_by(*args, **params).list()
@@ -1032,7 +1032,7 @@ class Query(object):
"""DEPRECATED. use query.filter(whereclause).all(), or query.from_statement(statement).all()"""
ret = self._extension.select(self, arg=arg, **kwargs)
- if ret is not mapper.EXT_PASS:
+ if ret is not mapper.EXT_CONTINUE:
return ret
return self._build_select(arg, **kwargs).all()
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index d248c0dd0..6a9c4164f 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -5,7 +5,7 @@
# the MIT License: http://www.opensource.org/licenses/mit-license.php
from sqlalchemy import sql, util, exceptions, sql_util
-from sqlalchemy.orm.interfaces import MapperExtension, EXT_PASS
+from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE
all_cascades = util.Set(["delete", "delete-orphan", "all", "merge",
"expunge", "save-update", "refresh-expire", "none"])
@@ -134,10 +134,10 @@ class ExtensionCarrier(MapperExtension):
def _do(self, *args, **kwargs):
for elem in self.__elements:
ret = getattr(elem, funcname)(*args, **kwargs)
- if ret is not EXT_PASS:
+ if ret is not EXT_CONTINUE:
return ret
else:
- return EXT_PASS
+ return EXT_CONTINUE
return _do
init_instance = _create_do('init_instance')