From 7f91210e945fe24d95f88c47a726bf4959925f96 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 18 Jan 2010 21:29:55 +0000 Subject: [PATCH] modernized "adjacencytree" example --- .../__init__.py | 0 examples/adjacency_list/adjacency_list.py | 139 ++++++++++++++++++ examples/adjacencytree/basic_tree.py | 129 ---------------- 3 files changed, 139 insertions(+), 129 deletions(-) rename examples/{adjacencytree => adjacency_list}/__init__.py (100%) create mode 100644 examples/adjacency_list/adjacency_list.py delete mode 100644 examples/adjacencytree/basic_tree.py diff --git a/examples/adjacencytree/__init__.py b/examples/adjacency_list/__init__.py similarity index 100% rename from examples/adjacencytree/__init__.py rename to examples/adjacency_list/__init__.py diff --git a/examples/adjacency_list/adjacency_list.py b/examples/adjacency_list/adjacency_list.py new file mode 100644 index 0000000000..3bf20dc5f8 --- /dev/null +++ b/examples/adjacency_list/adjacency_list.py @@ -0,0 +1,139 @@ +""" +An example of a dictionary-of-dictionaries structure mapped using +an adjacency list model + +""" + +from sqlalchemy import MetaData, Table, Column, Sequence, ForeignKey,\ + Integer, String, create_engine + +from sqlalchemy.orm import sessionmaker, mapper, relation, backref,\ + eagerload_all + +from sqlalchemy.orm.collections import attribute_mapped_collection + +metadata = MetaData() + +tree_table = Table('tree', metadata, + Column('id', Integer, primary_key=True), + Column('parent_id', Integer, ForeignKey('tree.id')), + Column('name', String(50), nullable=False) +) + +class TreeNode(object): + def __init__(self, name, parent=None): + self.name = name + self.parent = parent + + def append(self, nodename): + self.children[nodename] = TreeNode(nodename, parent=self) + + def __repr__(self): + return "TreeNode(name=%r, id=%r, parent_id=%r)" % ( + self.name, + self.id, + self.parent_id + ) + +def dump_tree(node, indent=0): + + return " " * indent + repr(node) + \ + "\n" + \ + "".join([ + dump_tree(c, indent +1) + for c in node.children.values()] + ) + + +mapper(TreeNode, tree_table, properties={ + 'children': relation(TreeNode, + + # cascade deletions + cascade="all", + + # many to one + adjacency list - remote_side + # is required to reference the 'remote' + # column in the join condition. + backref=backref("parent", remote_side=tree_table.c.id), + + # children will be represented as a dictionary + # on the "name" attribute. + collection_class=attribute_mapped_collection('name'), + ) + }) + +if __name__ == '__main__': + engine = create_engine('sqlite://', echo=True) + + def msg(msg): + print "\n\n\n" + "-" * len(msg) + print msg + print "-" * len(msg) + + msg("Creating Tree Table:") + + metadata.create_all(engine) + + # session. using expire_on_commit=False + # so that the session's contents are not expired + # after each transaction commit. + session = sessionmaker(engine, expire_on_commit=False)() + + node = TreeNode('rootnode') + node.append('node1') + node.append('node3') + + node2 = TreeNode('node2') + node2.append('subnode1') + node.children['node2'] = node2 + node.children['node2'].append('subnode2') + + msg("Created new tree structure:") + + print dump_tree(node) + + msg("flush + commit:") + + session.add(node) + session.commit() + + msg("Tree After Save:") + + print dump_tree(node) + + node.append('node4') + node.children['node4'].append('subnode3') + node.children['node4'].append('subnode4') + node.children['node4'].children['subnode3'].append('subsubnode1') + + # mark node1 as deleted and remove + session.delete(node.children['node1']) + + msg("Removed node1. flush + commit:") + session.commit() + + print "\n\n\n----------------------------" + print "Tree After Save:" + print "----------------------------" + + # expire the "children" collection so that + # it reflects the deletion of "node1". + session.expire(node, ['children']) + print dump_tree(node) + + msg("Emptying out the session entirely, " + "selecting tree on root, using eager loading to join four levels deep.") + session.expunge_all() + node = session.query(TreeNode).\ + options(eagerload_all("children", "children", + "children", "children")).\ + filter(TreeNode.name=="rootnode").\ + first() + + msg("Full Tree:") + print dump_tree(node) + + msg( "Marking root node as deleted, flush + commit:" ) + + session.delete(node) + session.commit() diff --git a/examples/adjacencytree/basic_tree.py b/examples/adjacencytree/basic_tree.py deleted file mode 100644 index dec03e5504..0000000000 --- a/examples/adjacencytree/basic_tree.py +++ /dev/null @@ -1,129 +0,0 @@ -"""A basic Adjacency List model tree.""" - -from sqlalchemy import MetaData, Table, Column, Sequence, ForeignKey -from sqlalchemy import Integer, String -from sqlalchemy.orm import create_session, mapper, relation, backref -from sqlalchemy.orm.collections import attribute_mapped_collection - -metadata = MetaData('sqlite:///') -metadata.bind.echo = True - -trees = Table('treenodes', metadata, - Column('id', Integer, Sequence('treenode_id_seq', optional=True), - primary_key=True), - Column('parent_id', Integer, ForeignKey('treenodes.id'), nullable=True), - Column('name', String(50), nullable=False)) - - -class TreeNode(object): - """a rich Tree class which includes path-based operations""" - def __init__(self, name): - 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[node.name] = 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) - -mapper(TreeNode, trees, properties={ - 'children': relation(TreeNode, cascade="all", - backref=backref("parent", remote_side=[trees.c.id]), - collection_class=attribute_mapped_collection('name'), - lazy=False, join_depth=3)}) - -print "\n\n\n----------------------------" -print "Creating Tree Table:" -print "----------------------------" - -trees.create() - -node2 = TreeNode('node2') -node2.append('subnode1') -node = TreeNode('rootnode') -node.append('node1') -node.append(node2) -node.append('node3') -node.children['node2'].append('subnode2') - -print "\n\n\n----------------------------" -print "Created new tree structure:" -print "----------------------------" - -print node.print_nodes() - -print "\n\n\n----------------------------" -print "Flushing:" -print "----------------------------" - -session = create_session() -session.add(node) -session.flush() - -print "\n\n\n----------------------------" -print "Tree After Save:" -print "----------------------------" - -print node.print_nodes() - -node.append('node4') -node.children['node4'].append('subnode3') -node.children['node4'].append('subnode4') -node.children['node4'].children['subnode3'].append('subsubnode1') -del node.children['node1'] - -print "\n\n\n----------------------------" -print "Modified the tree" -print "(added node4, node4/subnode3, node4/subnode4," -print "node4/subnode3/subsubnode1, deleted node1):" -print "----------------------------" - -print node.print_nodes() - -print "\n\n\n----------------------------" -print "Flushing:" -print "----------------------------" -session.flush() - -print "\n\n\n----------------------------" -print "Tree After Save:" -print "----------------------------" - -print node.print_nodes() - -nodeid = node.id - -print "\n\n\n----------------------------" -print "Clearing session, selecting " -print "tree new where node_id=%d:" % nodeid -print "----------------------------" - -session.expunge_all() -t = session.query(TreeNode).filter(TreeNode.id==nodeid)[0] - -print "\n\n\n----------------------------" -print "Full Tree:" -print "----------------------------" -print t.print_nodes() - -print "\n\n\n----------------------------" -print "Marking root node as deleted" -print "and flushing:" -print "----------------------------" -session.delete(t) -session.flush() -- 2.47.3