From: Jason Kirtland Date: Thu, 28 Jun 2007 20:04:52 +0000 (+0000) Subject: - OrderedDict shouldn't send None to update, never know who might be watching X-Git-Tag: rel_0_4_6~167 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=049ff220d56758658e37c3d9359f587e4c474735;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - OrderedDict shouldn't send None to update, never know who might be watching (breaks use as a collection class) - Update MapperExtension in byroot_tree example, finish updates for new collections. --- diff --git a/examples/adjacencytree/byroot_tree.py b/examples/adjacencytree/byroot_tree.py index a56df74657..bc187ff625 100644 --- a/examples/adjacencytree/byroot_tree.py +++ b/examples/adjacencytree/byroot_tree.py @@ -4,6 +4,7 @@ advantage of a custom MapperExtension to assemble incoming nodes into their corr from sqlalchemy import * from sqlalchemy.orm import * +from sqlalchemy.orm.collections import MappedCollection, collection_adapter from sqlalchemy.util import OrderedDict engine = create_engine('sqlite:///:memory:', echo=True) @@ -29,14 +30,13 @@ treedata = Table( ) -class NodeList(OrderedDict): - """subclasses OrderedDict to allow usage as a list-based property.""" - - def append(self, node): - self[node.name] = node - def remove(self, node): - del self[node.name] - +class NodeList(OrderedDict, MappedCollection): + """Mix OrderedDict and MappedCollection to create a dict-like collection class that keys off node names.""" + + def __init__(self, *args, **kw): + MappedCollection.__init__(self, keyfunc=lambda node: node.name) + OrderedDict.__init__(self, *args, **kw) + class TreeNode(object): """a hierarchical Tree class, which adds the concept of a "root node". The root is the topmost node in a tree, or in other words a node whose parent ID is NULL. @@ -55,7 +55,7 @@ class TreeNode(object): def _set_root(self, root): self.root = root - for c in self.children: + for c in self.children.values(): c._set_root(root) def append(self, node): @@ -92,19 +92,21 @@ class TreeLoader(MapperExtension): connection.execute(mapper.mapped_table.update(TreeNode.c.id==instance.id, values=dict(root_node_id=instance.id))) instance.root_id = instance.id - def append_result(self, mapper, selectcontext, row, instance, identitykey, result, isnew): + def append_result(self, mapper, selectcontext, row, instance, result, **flags): """runs as results from a SELECT statement are processed, and newly created or already-existing instances that correspond to each row are appended to result lists. This method will only append root nodes to the result list, and will attach child nodes to their appropriate parent node as they arrive from the select results. This allows a SELECT statement which returns both root and child nodes in one query to return a list of "roots".""" + isnew = flags.get('isnew', False) + if instance.parent_id is None: result.append(instance) else: if isnew or selectcontext.populate_existing: parentnode = selectcontext.identity_map[mapper.identity_key(instance.parent_id)] - parentnode.children.append_without_event(instance) + collection_adapter(parentnode.children).append_without_event(instance) # fire off lazy loader before the instance is part of the session instance.children return False diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index ee51c076e5..9047d5c414 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -260,7 +260,10 @@ class OrderedDict(dict): def __init__(self, d=None, **kwargs): self._list = [] - self.update(d, **kwargs) + if d is None: + self.update(**kwargs) + else: + self.update(d, **kwargs) def keys(self): return list(self._list)