From: Mike Bayer Date: Fri, 14 Oct 2005 06:35:16 +0000 (+0000) Subject: (no commit message) X-Git-Tag: rel_0_1_0~546 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c877ce8026ca7a41498f0d18699520a817eb92ca;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git --- diff --git a/lib/sqlalchemy/mapper.py b/lib/sqlalchemy/mapper.py index 0912ac9849..e787939eb4 100644 --- a/lib/sqlalchemy/mapper.py +++ b/lib/sqlalchemy/mapper.py @@ -357,7 +357,8 @@ class Mapper(object): self.columntoproperty[column][0].setattr(obj, value) def save_obj(self, objects, uow): - # try to get inserts to be en-masse with the "guess-the-id" thing maybe + """called by a UnitOfWork object to save objects, which involves either an INSERT + or an UPDATE statement for each table used by this mapper, for each element of the list.""" for table in self.tables: # loop thru tables in the outer loop, objects on the inner loop. @@ -407,6 +408,8 @@ class Mapper(object): self.extension.after_insert(self, obj) def delete_obj(self, objects, uow): + """called by a UnitOfWork object to delete objects, which involves a + DELETE statement for each table used by this mapper, for each object in the list.""" for table in self.tables: delete = [] for obj in objects: @@ -428,6 +431,9 @@ class Mapper(object): raise "ConcurrencyError - updated rowcount does not match number of objects updated" def register_dependencies(self, *args, **kwargs): + """called by an instance of objectstore.UOWTransaction to register + which mappers are dependent on which, as well as DependencyProcessor + objects which will process lists of objects in between saves and deletes.""" for prop in self.props.values(): prop.register_dependencies(*args, **kwargs) @@ -816,7 +822,7 @@ class PropertyLoader(MapperProperty): else: for obj in deplist: if self.direction == PropertyLoader.RIGHT: - task.requires_save(obj) + task.append(obj) childlist = getlist(obj) if childlist is None: return uowcommit.register_saved_list(childlist) @@ -824,13 +830,13 @@ class PropertyLoader(MapperProperty): for child in childlist.added_items(): self.primaryjoin.accept_visitor(setter) if self.direction == PropertyLoader.LEFT: - task.requires_save(child) + task.append(child) if self.direction != PropertyLoader.RIGHT or len(childlist.added_items()) == 0: clearkeys = True for child in childlist.deleted_items(): self.primaryjoin.accept_visitor(setter) if self.direction == PropertyLoader.LEFT: - task.requires_save(child) + task.append(child) def _sync_foreign_keys(self, binary, obj, child, associationrow, clearkeys): """given a binary clause with an = operator joining two table columns, synchronizes the values diff --git a/lib/sqlalchemy/objectstore.py b/lib/sqlalchemy/objectstore.py index 219d4d70e9..048c01d283 100644 --- a/lib/sqlalchemy/objectstore.py +++ b/lib/sqlalchemy/objectstore.py @@ -197,20 +197,17 @@ class UnitOfWork(object): commit_context.append_task(obj) else: for obj in [n for n in self.new] + [d for d in self.dirty]: - print "going to save.... " + obj.__class__.__name__ + repr(id(obj)) if self.deleted.contains(obj): continue commit_context.append_task(obj) for item in self.modified_lists: obj = item.obj - print "list on obj " + obj.__class__.__name__ + repr(id(obj)) + " is modified? " if self.deleted.contains(obj): continue commit_context.append_task(obj, listonly = True) for o in item.added_items() + item.deleted_items(): commit_context.append_task(o, listonly = False) for obj in self.deleted: - #print "going to delete.... " + repr(obj) commit_context.add_item_to_delete(obj) engines = util.HashSet() @@ -262,9 +259,8 @@ class UOWTransaction(object): def append_task(self, obj, listonly = False): mapper = object_mapper(obj) self.mappers.append(mapper) - task = self.get_task_by_mapper(mapper, listonly = listonly) - print "APPENDING TASK " + str(task) - task.append(obj) + task = self.get_task_by_mapper(mapper) + task.append(obj, listonly) def add_item_to_delete(self, obj): mapper = object_mapper(obj) @@ -272,16 +268,11 @@ class UOWTransaction(object): task = self.get_task_by_mapper(mapper, True) task.append(obj) - def get_task_by_mapper(self, mapper, isdelete = False, listonly = None): + def get_task_by_mapper(self, mapper, isdelete = False): try: - task = self.tasks[(mapper, isdelete)] - if listonly is not None and (task.listonly is None or task.listonly is True): - task.listonly = listonly - return task + return self.tasks[(mapper, isdelete)] except KeyError: - if listonly is None: - listonly = False - return self.tasks.setdefault((mapper, isdelete), UOWTask(mapper, isdelete, listonly)) + return self.tasks.setdefault((mapper, isdelete), UOWTask(mapper, isdelete)) def get_objects(self, mapper, isdelete = False): try: @@ -343,7 +334,7 @@ class UOWTransaction(object): bymapper = {} def sort(node, isdel, res): - print "Sort: " + (node and str(node.item) or 'None') + #print "Sort: " + (node and str(node.item) or 'None') if node is None: return res task = bymapper.get((node.item, isdel), None) @@ -375,39 +366,36 @@ class UOWTransaction(object): return tasklist class UOWTask(object): - def __init__(self, mapper, isdelete = False, listonly = False): + def __init__(self, mapper, isdelete = False): self.mapper = mapper self.isdelete = isdelete -# self.objects = util.HashSet(ordered = True) self.objects = util.OrderedDict() self.dependencies = [] - self.listonly = listonly self.iscircular = False - print "new task " + str(self) - def append(self, obj): - #self.objects.append(obj) - self.objects[obj] = True + def append(self, obj, listonly = False): + self.objects[obj] = listonly and self.objects.get(obj, True) + #print "Task " + str(self) + " append object " + obj.__class__.__name__ + "/" + repr(id(obj)) + " listonly " + repr(listonly) + "/" + repr(self.objects[obj]) def requires_save(self, obj): - print "requires save! " + repr(obj) - pass + self.objects[obj] = False + #print "Task " + str(self) + " requires " + (self.isdelete and "delete " or "save ") + obj.__class__.__name__ + "/" + repr(id(obj)) def execute(self, trans): if self.iscircular: - print "creating circular task for " + str(self) + #print "creating circular task for " + str(self) task = self._sort_circular_dependencies(trans) if task is not None: task.execute_circular(trans) return - obj_list = self.objects.keys() - if not self.listonly and not self.isdelete: + obj_list = [o for o, listonly in self.objects.iteritems() if not listonly] + if not self.isdelete: self.mapper.save_obj(obj_list, trans) for dep in self.dependencies: (processor, targettask) = dep processor.process_dependencies(targettask, targettask.objects.keys(), trans, delete = self.isdelete) - if not self.listonly and self.isdelete: + if self.isdelete: self.mapper.delete_obj(obj_list, trans) def execute_circular(self, trans): @@ -427,7 +415,7 @@ class UOWTask(object): try: return d[obj] except KeyError: - t = UOWTask(self.mapper, self.isdelete, self.listonly) + t = UOWTask(self.mapper, self.isdelete) t.taskhash = d d[obj] = t return t @@ -442,7 +430,7 @@ class UOWTask(object): try: l = dp[processor] except KeyError: - l = UOWTask(None, None, True) + l = UOWTask(None, None) dp[processor] = l return l @@ -474,9 +462,7 @@ class UOWTask(object): return None def make_task_tree(node, parenttask): - if node is None: - return - parenttask.append(node.item) + parenttask.append(node.item, self.objects[node.item]) if dependencies.has_key(node.item): for processor, deptask in dependencies[node.item].iteritems(): parenttask.dependencies.append((processor, deptask)) @@ -485,10 +471,10 @@ class UOWTask(object): t2 = make_task_tree(n, t) return t - t = UOWTask(self.mapper, self.isdelete, self.listonly) + t = UOWTask(self.mapper, self.isdelete) t.taskhash = d make_task_tree(head, t) - t._print_circular() + #t._print_circular() return t def _print_circular(t): @@ -504,9 +490,9 @@ class UOWTask(object): else: mapperstr = "(no mapper)" if self.isdelete: - return mapperstr + " deletes - listonly " + repr(self.listonly) + " " + repr(id(self)) + return mapperstr + "/deletes/" + repr(id(self)) else: - return mapperstr + " saves - listonly " + repr(self.listonly) + repr(id(self)) + return mapperstr + "/saves/" + repr(id(self)) uow = util.ScopedRegistry(lambda: UnitOfWork(), "thread")