summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-02-07 23:58:17 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2010-02-07 23:58:17 +0000
commit03167fb4bbb2d4a1d68ef04dff02ed2033b4f138 (patch)
tree858b2e36b83467b8f4c2a3b72b9e4fc4bd7cadaa /lib/sqlalchemy
parent52ab4041affc8618892d82d82281eedc5b3d0b6f (diff)
downloadsqlalchemy-03167fb4bbb2d4a1d68ef04dff02ed2033b4f138.tar.gz
- Now uses sqlalchemy.orm.exc.DetachedInstanceError when an
attribute load or refresh action fails due to object being detached from any Session. UnboundExecutionError is specific to engines bound to sessions and statements.
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/dynamic.py5
-rw-r--r--lib/sqlalchemy/orm/exc.py4
-rw-r--r--lib/sqlalchemy/orm/mapper.py18
-rw-r--r--lib/sqlalchemy/orm/strategies.py8
4 files changed, 19 insertions, 16 deletions
diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py
index 456bcd34e..308d69fe8 100644
--- a/lib/sqlalchemy/orm/dynamic.py
+++ b/lib/sqlalchemy/orm/dynamic.py
@@ -12,7 +12,8 @@ basic add/delete mutation.
"""
from sqlalchemy import log, util
-import sqlalchemy.exceptions as sa_exc
+from sqlalchemy import exc as sa_exc
+from sqlalchemy.orm import exc as sa_exc
from sqlalchemy.sql import operators
from sqlalchemy.orm import (
attributes, object_session, util as mapperutil, strategies, object_mapper
@@ -234,7 +235,7 @@ class AppenderMixin(object):
if sess is None:
sess = object_session(instance)
if sess is None:
- raise sa_exc.UnboundExecutionError(
+ raise orm_exc.DetachedInstanceError(
"Parent instance %s is not bound to a Session, and no "
"contextual session is established; lazy load operation "
"of attribute '%s' cannot proceed" % (
diff --git a/lib/sqlalchemy/orm/exc.py b/lib/sqlalchemy/orm/exc.py
index 8b52eec8a..431acc15c 100644
--- a/lib/sqlalchemy/orm/exc.py
+++ b/lib/sqlalchemy/orm/exc.py
@@ -23,7 +23,9 @@ class FlushError(sa.exc.SQLAlchemyError):
class UnmappedError(sa.exc.InvalidRequestError):
"""TODO"""
-
+class DetachedInstanceError(sa.exc.SQLAlchemyError):
+ """An attempt to access unloaded attributes on a mapped instance that is detached."""
+
class UnmappedInstanceError(UnmappedError):
"""An mapping operation was requested for an unknown instance."""
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 2bdf2b847..63ad20bca 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -22,7 +22,7 @@ deque = __import__('collections').deque
from sqlalchemy import sql, util, log, exc as sa_exc
from sqlalchemy.sql import expression, visitors, operators, util as sqlutil
-from sqlalchemy.orm import attributes, exc, sync
+from sqlalchemy.orm import attributes, sync, exc as orm_exc
from sqlalchemy.orm.interfaces import (
MapperProperty, EXT_CONTINUE, PropComparator
)
@@ -1123,9 +1123,9 @@ class Mapper(object):
except KeyError:
prop = self._props.get(column.key, None)
if prop:
- raise exc.UnmappedColumnError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop)))
+ raise orm_exc.UnmappedColumnError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop)))
else:
- raise exc.UnmappedColumnError("No column %s is configured on mapper %s..." % (column, self))
+ raise orm_exc.UnmappedColumnError("No column %s is configured on mapper %s..." % (column, self))
# TODO: improve names?
def _get_state_attr_by_column(self, state, column):
@@ -1319,7 +1319,7 @@ class Mapper(object):
instance = uowtransaction.session.identity_map[instance_key]
existing = attributes.instance_state(instance)
if not uowtransaction.is_deleted(existing):
- raise exc.FlushError(
+ raise orm_exc.FlushError(
"New instance %s with identity key %s conflicts with persistent instance %s" %
(state_str(state), instance_key, state_str(existing)))
if self._should_log_debug:
@@ -1460,7 +1460,7 @@ class Mapper(object):
if connection.dialect.supports_sane_rowcount:
if rows != len(update):
- raise exc.ConcurrentModificationError(
+ raise orm_exc.ConcurrentModificationError(
"Updated rowcount %d does not match number of objects updated %d" %
(rows, len(update)))
@@ -1600,7 +1600,7 @@ class Mapper(object):
statement = table.delete(clause)
c = connection.execute(statement, del_objects)
if c.supports_sane_multi_rowcount() and c.rowcount != len(del_objects):
- raise exc.ConcurrentModificationError("Deleted rowcount %d does not match "
+ raise orm_exc.ConcurrentModificationError("Deleted rowcount %d does not match "
"number of objects deleted %d" % (c.rowcount, len(del_objects)))
for state, mapper, connection in tups:
@@ -1725,7 +1725,7 @@ class Mapper(object):
if not currentload and version_id_col is not None and context.version_check and \
self._get_state_attr_by_column(state, self.version_id_col) != row[version_id_col]:
- raise exc.ConcurrentModificationError(
+ raise orm_exc.ConcurrentModificationError(
"Instance '%s' version of %s does not match %s"
% (state_str(state), self._get_state_attr_by_column(state, self.version_id_col), row[version_id_col]))
elif refresh_state:
@@ -1928,7 +1928,7 @@ def _load_scalar_attributes(state, attribute_names):
mapper = _state_mapper(state)
session = _state_session(state)
if not session:
- raise sa_exc.UnboundExecutionError("Instance %s is not bound to a Session; "
+ raise orm_exc.DetachedInstanceError("Instance %s is not bound to a Session; "
"attribute refresh operation cannot proceed" % (state_str(state)))
has_key = _state_has_identity(state)
@@ -1948,4 +1948,4 @@ def _load_scalar_attributes(state, attribute_names):
# if instance is pending, a refresh operation may not complete (even if PK attributes are assigned)
if has_key and result is None:
- raise exc.ObjectDeletedError("Instance '%s' has been deleted." % state_str(state))
+ raise orm_exc.ObjectDeletedError("Instance '%s' has been deleted." % state_str(state))
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 0970f3836..33e60491a 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -6,11 +6,11 @@
"""sqlalchemy.orm.interfaces.LoaderStrategy implementations, and related MapperOptions."""
-import sqlalchemy.exceptions as sa_exc
+from sqlalchemy import exc as sa_exc
from sqlalchemy import sql, util, log
from sqlalchemy.sql import util as sql_util
from sqlalchemy.sql import visitors, expression, operators
-from sqlalchemy.orm import mapper, attributes, interfaces
+from sqlalchemy.orm import mapper, attributes, interfaces, exc as orm_exc
from sqlalchemy.orm.interfaces import (
LoaderStrategy, StrategizedOption, MapperOption, PropertyOption,
serialize_path, deserialize_path, StrategizedProperty
@@ -291,7 +291,7 @@ class LoadDeferredColumns(object):
session = sessionlib._state_session(state)
if session is None:
- raise sa_exc.UnboundExecutionError(
+ raise orm_exc.DetachedInstanceError(
"Parent instance %s is not bound to a Session; "
"deferred load operation of attribute '%s' cannot proceed" %
(mapperutil.state_str(state), self.key)
@@ -556,7 +556,7 @@ class LoadLazyAttribute(object):
session = sessionlib._state_session(state)
if session is None:
- raise sa_exc.UnboundExecutionError(
+ raise orm_exc.DetachedInstanceError(
"Parent instance %s is not bound to a Session; "
"lazy load operation of attribute '%s' cannot proceed" %
(mapperutil.state_str(state), self.key)