I should note that the relationship you are actually trying to set up includes a circular relationship between two individual rows. by default this is impossible to accomplish with only INSERT statements and not violate foreign key constraints. to break this circular relation you have to also add a special flag "post_update=True" to one side of the circle, which will add an extra UPDATE statement to the commit.
n_mapper = mapper(Node, node_table, properties={ 'parent': relation( Node, lazy=True, primaryjoin=node_table.c.parent_id==node_table.c.id, foreignkey=node_table.c.id, uselist=False ), 'children': relation( Node, primaryjoin=node_table.c.id==node_table.c.parent_id, lazy=True, cascade="all" ), 'previous_sibling': relation( Node, primaryjoin=node_table.c.prev_sibling_id==node_table.c.id, foreignkey=node_table.c.id, lazy=True, uselist=False ), 'next_sibling': relation( Node, primaryjoin=node_table.c.next_sibling_id==node_table.c.id, foreignkey=node_table.c.id, lazy=True, uselist=False, post_update=True, ) }) produces the statements: [2006-09-05 14:11:47,504] [engine]: BEGIN [2006-09-05 14:11:47,510] [engine]: INSERT INTO node (path, parent_id, prev_sibling_id, next_sibling_id) VALUES (?, ?, ?, ?) [2006-09-05 14:11:47,511] [engine]: ['root', None, None, None] [2006-09-05 14:11:47,516] [engine]: INSERT INTO node (path, parent_id, prev_sibling_id, next_sibling_id) VALUES (?, ?, ?, ?) [2006-09-05 14:11:47,516] [engine]: ['first', 1, None, None] [2006-09-05 14:11:47,521] [engine]: INSERT INTO node (path, parent_id, prev_sibling_id, next_sibling_id) VALUES (?, ?, ?, ?) [2006-09-05 14:11:47,522] [engine]: ['second', 1, 2, None] [2006-09-05 14:11:47,527] [engine]: UPDATE node SET path=? WHERE node.id = ? [2006-09-05 14:11:47,527] [engine]: ['root', 1] [2006-09-05 14:11:47,531] [engine]: UPDATE node SET path=?, parent_id=?, next_sibling_id=? WHERE node.id = ? [2006-09-05 14:11:47,532] [engine]: ['first', 1, 3, 2] [2006-09-05 14:11:47,536] [engine]: UPDATE node SET path=?, parent_id=?, prev_sibling_id=? WHERE node.id = ? [2006-09-05 14:11:47,537] [engine]: ['second', 1, 2, 3] [2006-09-05 14:11:47,539] [engine]: COMMIT On Sep 5, 2006, at 10:12 AM, Nick Joyce wrote: > I am attempting to extend the self referential example in the docs > http://www.sqlalchemy.org/docs/index.myt? > paged=no#advdatamapping_circular > by adding properties 'prev_sibling' and 'next_sibling'. (See attached > script) > > When run, the following exception is raised: > > Traceback (most recent call last): > File "tree.py", line 79, in ? > session.flush() > File "build/bdist.linux-i686/egg/sqlalchemy/orm/session.py", line > 234, > in flush > File "build/bdist.linux-i686/egg/sqlalchemy/orm/unitofwork.py", line > 197, in flush > File "build/bdist.linux-i686/egg/sqlalchemy/orm/unitofwork.py", line > 359, in execute > File "build/bdist.linux-i686/egg/sqlalchemy/orm/unitofwork.py", line > 407, in _sort_dependencies > File "build/bdist.linux-i686/egg/sqlalchemy/orm/unitofwork.py", line > 395, in sort_hier > File "build/bdist.linux-i686/egg/sqlalchemy/orm/unitofwork.py", line > 800, in _sort_circular_dependencies > File "build/bdist.linux-i686/egg/sqlalchemy/orm/topological.py", > line > 139, in sort > sqlalchemy.exceptions.FlushError: Circular dependency detected > {<Node(path=first)> (idself=1079711436): {<Node(path=second)> > (idself=1079711468): True, <Node(path=root)> (idself=1079711404): > True}, <Node(path=root)> (idself=1079711404): {<Node(path=second)> > (idself=1079711468): True, <Node(path=first)> (idself=1079711436): > True}, <Node(path=second)> (idself=1079711468): {<Node(path=first)> > (idself=1079711436): True, <Node(path=root)> (idself=1079711404): > True}}[] > > I am doing something wrong? If so can someone point me in the right > direction ... > > Thanks, > > Nick > import sqlalchemy.mods.threadlocal > from sqlalchemy import * > > engine = create_engine('sqlite:///:memory:', echo=True); > metadata = BoundMetaData(engine) > > node_table = Table('node', metadata, > Column('id', Integer, primary_key=True), > Column('path', String(50), nullable=False), > Column('parent_id', Integer, ForeignKey('node.id'), > nullable=True), > Column('prev_sibling_id', Integer, ForeignKey('node.id'), > nullable=True), > Column('next_sibling_id', Integer, ForeignKey('node.id'), > nullable=True) > ) > > class Node(object): > def __init__(self, path=''): > self.path = path > > def has_child_nodes(self): > return len(self.children) == 0 > > def append_child(self, child): > try: > lc = self.children[len(self.children) - 1] > except IndexError, e: > lc = None > > self.children.append(child) > > child.parent = self > > if lc is not None: > lc.next_sibling = child > child.previous_sibling = lc > > def __repr__(self): > return '<Node(path=%s)>' % self.path > > n_mapper = mapper(Node, node_table, properties={ > 'parent': relation( > Node, > lazy=True, > primaryjoin=node_table.c.parent_id==node_table.c.id, > uselist=False > ), > 'children': relation( > Node, > primaryjoin=node_table.c.id==node_table.c.parent_id, > lazy=True, > cascade="all, delete-orphan" > ), > 'previous_sibling': relation( > Node, > primaryjoin=node_table.c.prev_sibling_id==node_table.c.id, > lazy=True, > uselist=False > ), > 'next_sibling': relation( > Node, > primaryjoin=node_table.c.next_sibling_id==node_table.c.id, > lazy=True, > uselist=False > ) > }) > > if __name__ == '__main__': > node_table.create() > > root = Node('root') > first = Node('first') > second = Node('second') > > root.append_child(first) > root.append_child(second) > > print first==second.previous_sibling > > session = objectstore.session > > session.flush() > ---------------------------------------------------------------------- > --- > Using Tomcat but need to do more? Need to support web services, > security? > Get stuff done quickly with pre-integrated technology to make your > job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache > Geronimo > http://sel.as-us.falkag.net/sel? > cmd=lnk&kid=120709&bid=263057&dat=121642______________________________ > _________________ > Sqlalchemy-users mailing list > Sqlalchemy-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Sqlalchemy-users mailing list Sqlalchemy-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users