summaryrefslogtreecommitdiff
path: root/examples/nested_sets
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-04-27 17:21:31 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-04-27 17:21:31 -0400
commit8cdb4543bd7a85bef0286433576aafe0fb8e7c4c (patch)
tree4f69b10e11a0cb6e58f0bab326a534b7dbcd12f8 /examples/nested_sets
parent5f51d409ccda1033a41256dfc28e46bc6923521d (diff)
downloadsqlalchemy-8cdb4543bd7a85bef0286433576aafe0fb8e7c4c.tar.gz
modernize some more examples
Diffstat (limited to 'examples/nested_sets')
-rw-r--r--examples/nested_sets/nested_sets.py98
1 files changed, 53 insertions, 45 deletions
diff --git a/examples/nested_sets/nested_sets.py b/examples/nested_sets/nested_sets.py
index e35ea61c3..8225a09f2 100644
--- a/examples/nested_sets/nested_sets.py
+++ b/examples/nested_sets/nested_sets.py
@@ -6,47 +6,17 @@ http://www.intelligententerprise.com/001020/celko.jhtml
from sqlalchemy import (create_engine, Column, Integer, String, select, case,
func)
-from sqlalchemy.orm import sessionmaker, MapperExtension, aliased
+from sqlalchemy.orm import Session, aliased
from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy import event
-engine = create_engine('sqlite://', echo=True)
Base = declarative_base()
-class NestedSetExtension(MapperExtension):
- def before_insert(self, mapper, connection, instance):
- if not instance.parent:
- instance.left = 1
- instance.right = 2
- else:
- personnel = mapper.mapped_table
- right_most_sibling = connection.scalar(
- select([personnel.c.rgt]).where(personnel.c.emp==instance.parent.emp)
- )
-
- connection.execute(
- personnel.update(personnel.c.rgt>=right_most_sibling).values(
- lft = case(
- [(personnel.c.lft>right_most_sibling, personnel.c.lft + 2)],
- else_ = personnel.c.lft
- ),
- rgt = case(
- [(personnel.c.rgt>=right_most_sibling, personnel.c.rgt + 2)],
- else_ = personnel.c.rgt
- )
- )
- )
- instance.left = right_most_sibling
- instance.right = right_most_sibling + 1
-
- # before_update() would be needed to support moving of nodes
- # after_delete() would be needed to support removal of nodes.
- # [ticket:1172] needs to be implemented for deletion to work as well.
-
class Employee(Base):
__tablename__ = 'personnel'
__mapper_args__ = {
- 'extension':NestedSetExtension(),
- 'batch':False # allows extension to fire for each instance before going to the next.
+ 'batch': False # allows extension to fire for each
+ # instance before going to the next.
}
parent = None
@@ -59,9 +29,44 @@ class Employee(Base):
def __repr__(self):
return "Employee(%s, %d, %d)" % (self.emp, self.left, self.right)
+@event.listens_for(Employee, "before_insert")
+def before_insert(mapper, connection, instance):
+ if not instance.parent:
+ instance.left = 1
+ instance.right = 2
+ else:
+ personnel = mapper.mapped_table
+ right_most_sibling = connection.scalar(
+ select([personnel.c.rgt]).
+ where(personnel.c.emp == instance.parent.emp)
+ )
+
+ connection.execute(
+ personnel.update(
+ personnel.c.rgt >= right_most_sibling).values(
+ lft=case(
+ [(personnel.c.lft > right_most_sibling,
+ personnel.c.lft + 2)],
+ else_=personnel.c.lft
+ ),
+ rgt=case(
+ [(personnel.c.rgt >= right_most_sibling,
+ personnel.c.rgt + 2)],
+ else_=personnel.c.rgt
+ )
+ )
+ )
+ instance.left = right_most_sibling
+ instance.right = right_most_sibling + 1
+
+ # before_update() would be needed to support moving of nodes
+ # after_delete() would be needed to support removal of nodes.
+
+engine = create_engine('sqlite://', echo=True)
+
Base.metadata.create_all(engine)
-session = sessionmaker(bind=engine)()
+session = Session(bind=engine)
albert = Employee(emp='Albert')
bert = Employee(emp='Bert')
@@ -81,23 +86,26 @@ fred.parent = chuck
session.add_all([albert, bert, chuck, donna, eddie, fred])
session.commit()
-print session.query(Employee).all()
+print(session.query(Employee).all())
# 1. Find an employee and all his/her supervisors, no matter how deep the tree.
ealias = aliased(Employee)
-print session.query(Employee).\
+print(session.query(Employee).\
filter(ealias.left.between(Employee.left, Employee.right)).\
- filter(ealias.emp=='Eddie').all()
+ filter(ealias.emp == 'Eddie').all())
-#2. Find the employee and all his/her subordinates. (This query has a nice symmetry with the first query.)
-print session.query(Employee).\
+#2. Find the employee and all his/her subordinates.
+# (This query has a nice symmetry with the first query.)
+print(session.query(Employee).\
filter(Employee.left.between(ealias.left, ealias.right)).\
- filter(ealias.emp=='Chuck').all()
+ filter(ealias.emp == 'Chuck').all())
-#3. Find the level of each node, so you can print the tree as an indented listing.
-for indentation, employee in session.query(func.count(Employee.emp).label('indentation') - 1, ealias).\
+#3. Find the level of each node, so you can print the tree
+# as an indented listing.
+for indentation, employee in session.query(
+ func.count(Employee.emp).label('indentation') - 1, ealias).\
filter(ealias.left.between(Employee.left, Employee.right)).\
group_by(ealias.emp).\
- order_by(ealias.left):
- print " " * indentation + str(employee)
+ order_by(ealias.left):
+ print(" " * indentation + str(employee))