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)

Reply via email to