Hi All, I am working on a modified version of basic_tree.py. The base demo simply appends nodes to a parent node. What I would like to do, is to be able to "prepend" nodes on a parent node, i.e. appending nodes before other nodes in the tree structure. For example, if a parent node has this structure:
Parent |--- Child 1 |--- Child 2 I would like to insert a new item like that: Parent |--- NewItem |--- Child 1 |--- Child 2 So, I have modified the basic demo NodeList class like this: class NodeList(OrderedDict): """subclasses OrderedDict to allow usage as a list-based property.""" def append(self, node): self[node.name] = node def insert(self, indx, node): self[node.name] = node self.move(node.name, indx) And then, to prepend an item, I simply do: node = TreeNode('rootnode') node.append('Child 1') node.append('Child 2') # More actions here... node.insert('NewItem') But this newitem gets inserted at the end (like it does when you use append() ). This happens if I call session.clear(), if I don't do that the item looks correctly inserted as a first item. I attach a small demo that shows my problem. Does anyone know what I am doing wrong or what I have misunderstood? Thank you for your suggestions. Andrea. "Imagination Is The Only Weapon In The War Against Reality." http://xoomer.virgilio.it/infinity77/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---
"""a basic Adjacency List model tree.""" from sqlalchemy import * from sqlalchemy.util import OrderedDict class NodeList(OrderedDict): """subclasses OrderedDict to allow usage as a list-based property.""" def append(self, node): self[node.name] = node def insert(self, indx, node): self[node.name] = node self.move(node.name, indx) def __iter__(self): return iter(self.values()) class TreeNode(object): """a rich Tree class which includes path-based operations""" def __init__(self, name): self.children = NodeList() self.name = name self.parent = None self.id = None self.parent_id = None def append(self, node): if isinstance(node, str): node = TreeNode(node) node.parent = self self.children.append(node) def insert(self, node): if isinstance(node, str): node = TreeNode(node) node.parent = self self.children.insert(0, node) def __repr__(self): return self._getstring(0, False) def __str__(self): return self._getstring(0, False) def _getstring(self, level, expand = False): s = (' ' * level) + "%s (%s,%s, %d)" % (self.name, self.id,self.parent_id,id(self)) + '\n' if expand: s += ''.join([n._getstring(level+1, True) for n in self.children.values()]) return s def print_nodes(self): return self._getstring(0, True) def RunBasicTree(clearSession=False): metadata = BoundMetaData('sqlite:///', echo=False) trees = Table('treenodes', metadata, Column('node_id', Integer, Sequence('treenode_id_seq',optional=False), primary_key=True), Column('parent_node_id', Integer, ForeignKey('treenodes.node_id'), nullable=True), Column('node_name', String(50), nullable=False), ) mapper(TreeNode, trees, properties=dict( id=trees.c.node_id, name=trees.c.node_name, parent_id=trees.c.parent_node_id, children=relation(TreeNode, cascade="all", backref=backref("parent", remote_side=[trees.c.node_id]), collection_class=NodeList), )) trees.create() node2 = TreeNode('node2') node2.append('subnode1') nodea = TreeNode('rootnode') nodea.append('node1') nodea.append(node2) nodea.append('node3') nodea.children['node2'].append('subnode2') session = create_session() session.save(nodea) session.flush() nodea.append('node4') nodea.children['node4'].append('subnode3') nodea.children['node4'].append('subnode4') nodea.children['node4'].children['subnode3'].append('subsubnode1') del nodea.children['node1'] session.flush() # ============================ # # Here I try to insert the node # ============================ # nodea.insert("DUMMY!") session.save(nodea) session.flush() nodeid = nodea.id if clearSession: print "\n\n\n----------------------------" print "Clearing session, selecting " print "tree new where node_id=%d:" % nodeid print "----------------------------" # If I don't clear the session, the item looks correctly # inserted as first child of the root session.clear() t = session.query(TreeNode).select(TreeNode.c.id==nodeid)[0] print "\n----------------------------" print "Full Tree:" print "----------------------------" print t.print_nodes() # ============================ # # Modify this variable clearSession to see the different behavior # ============================ # clearSession = True RunBasicTree(clearSession)