summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/mapper.py18
-rw-r--r--lib/sqlalchemy/orm/strategies.py53
2 files changed, 39 insertions, 32 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 3327f13c3..e07f691f4 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -220,12 +220,20 @@ class Mapper(object):
def _is_orphan(self, obj):
optimistic = has_identity(obj)
for (key,klass) in self.delete_orphans:
- if not getattr(klass, key).hasparent(obj, optimistic=optimistic):
- if not has_identity(obj):
- raise exceptions.FlushError("instance %s is an unsaved, pending instance and is an orphan (is not attached to any parent '%s' instance via that classes' '%s' attribute)" % (obj, klass.__name__, key))
- return True
+ if getattr(klass, key).hasparent(obj, optimistic=optimistic):
+ return False
else:
- return False
+ if len(self.delete_orphans):
+ if not has_identity(obj):
+ raise exceptions.FlushError("instance %s is an unsaved, pending instance and is an orphan (is not attached to %s)" %
+ (
+ obj,
+ ", nor ".join(["any parent '%s' instance via that classes' '%s' attribute" % (klass.__name__, key) for (key,klass) in self.delete_orphans])
+ ))
+ else:
+ return True
+ else:
+ return False
def _get_props(self):
self.compile()
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 6e5590bb0..c4b75f644 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -470,7 +470,6 @@ class EagerLoader(AbstractRelationLoader):
else:
decorated_row = decorator(row)
else:
- # AliasedClauses, keyed to the lead mapper used in the query
clauses = self.clauses_by_lead_mapper[selectcontext.mapper]
decorated_row = clauses._decorate_row(row)
# check for identity key
@@ -481,36 +480,36 @@ class EagerLoader(AbstractRelationLoader):
self.parent_property._get_strategy(LazyLoader).process_row(selectcontext, instance, row, identitykey, isnew)
return
- if not self.uselist:
- self.logger.debug("eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key))
- if isnew:
- # set a scalar object instance directly on the parent object,
- # bypassing SmartProperty event handlers.
- instance.__dict__[self.key] = self.mapper._instance(selectcontext, decorated_row, None)
+ # TODO: recursion check a speed hit...? try to get a "termination point" into the AliasedClauses
+ # or EagerRowAdapter ?
+ selectcontext.recursion_stack.add(self)
+ try:
+ if not self.uselist:
+ self.logger.debug("eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key))
+ if isnew:
+ # set a scalar object instance directly on the parent object,
+ # bypassing SmartProperty event handlers.
+ instance.__dict__[self.key] = self.mapper._instance(selectcontext, decorated_row, None)
+ else:
+ # call _instance on the row, even though the object has been created,
+ # so that we further descend into properties
+ self.mapper._instance(selectcontext, decorated_row, None)
else:
- # call _instance on the row, even though the object has been created,
- # so that we further descend into properties
- self.mapper._instance(selectcontext, decorated_row, None)
- else:
- if isnew:
- self.logger.debug("initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key))
- # call the SmartProperty's initialize() method to create a new, blank list
- l = getattr(instance.__class__, self.key).initialize(instance)
+ if isnew:
+ self.logger.debug("initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key))
+ # call the SmartProperty's initialize() method to create a new, blank list
+ l = getattr(instance.__class__, self.key).initialize(instance)
- # create an appender object which will add set-like semantics to the list
- appender = util.UniqueAppender(l.data)
+ # create an appender object which will add set-like semantics to the list
+ appender = util.UniqueAppender(l.data)
- # store it in the "scratch" area, which is local to this load operation.
- selectcontext.attributes[(instance, self.key)] = appender
- result_list = selectcontext.attributes[(instance, self.key)]
- self.logger.debug("eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key))
- # TODO: recursion check a speed hit...? try to get a "termination point" into the AliasedClauses
- # or EagerRowAdapter ?
- selectcontext.recursion_stack.add(self)
- try:
+ # store it in the "scratch" area, which is local to this load operation.
+ selectcontext.attributes[(instance, self.key)] = appender
+ result_list = selectcontext.attributes[(instance, self.key)]
+ self.logger.debug("eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key))
self.mapper._instance(selectcontext, decorated_row, result_list)
- finally:
- selectcontext.recursion_stack.remove(self)
+ finally:
+ selectcontext.recursion_stack.remove(self)
EagerLoader.logger = logging.class_logger(EagerLoader)