the treenodes table has no explicit sorting field, so by default it
will sort by either the row ID of the table or the primary key field.
the only operation that can be issued to the database when you add an
item to the list is INSERT, so this will always assemble new nodes as
the last element in the collection regardless of where they appear in
your python collection.

to have custom ordering of your list other than insert order, a new
column will need to be added to treenodes with which to sort by, and
your Node class will have to populate this field with an ordering
corresponding to its desired order in its parent collection.

this population can be performed pretty easily with this example by
just altering NodeList to additionally populate child items with a
"sort" field.

you then specify this column on the "children" relationship as the
"order_by" field.


On Mar 30, 11:51 am, "Andrea Gavana" <[EMAIL PROTECTED]> wrote:
> 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/
>
> [basic_tree.py]"""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)


--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to