Jonathan LaCour wrote: >> I am attempting to model a doubly-linked list, as follows: > > ... seems to do the trick. I had tried using backref's earlier, > but it was failing because I was specifying a "remote_side" > keyword argument to the backref(), which was making it blow up > with cycle detection exceptions for some reason.
Oops, spoke too soon! Here is a test case which shows something quite odd. I create some elements, link them together, and then walk the relations forward and backward, printing out the results. All seems fine. Then, I update the order of the linked list, and print them out forward, and they work okay, but when I print things out in reverse order, its all screwy. Any ideas? -------------------------------------------------------------------- from sqlalchemy import * from sqlalchemy.orm import * engine = create_engine('sqlite:///') metadata = MetaData(engine) Session = scoped_session( sessionmaker(bind=engine, autoflush=True, transactional=True) ) task_table = Table('task', metadata, Column('id', Integer, primary_key=True), Column('name', Unicode), Column('next_task_id', Integer, ForeignKey('task.id')), Column('previous_task_id', Integer, ForeignKey('task.id')) ) class Task(object): def __init__(self, **kw): for key, value in kw.items(): setattr(self, key, value) def __repr__(self): return '<Task :: %s>' % self.name Session.mapper(Task, task_table, properties={ 'next_task' : relation( Task, primaryjoin=task_table.c.next_task_id==task_table.c.id, uselist=False, remote_side=task_table.c.id, backref=backref( 'previous_task', primaryjoin=task_table.c.previous_task_id==task_table.c.id, uselist=False ) ), }) if __name__ == '__main__': metadata.create_all() t1 = Task(name=u'Item One') t2 = Task(name=u'Item Two') t3 = Task(name=u'Item Three') t4 = Task(name=u'Item Four') t5 = Task(name=u'Item Five') t6 = Task(name=u'Item Six') t1.next_task = t2 t2.next_task = t3 t3.next_task = t4 t4.next_task = t5 t5.next_task = t6 Session.commit() Session.clear() print '-' * 80 task = Task.query.filter_by(name=u'Item One').one() while task is not None: print task task = task.next_task print '-' * 80 print '-' * 80 task = Task.query.filter_by(name=u'Item Six').one() while task is not None: print task task = task.previous_task print '-' * 80 Session.clear() t1 = Task.query.filter_by(name=u'Item One').one() t2 = Task.query.filter_by(name=u'Item Two').one() t3 = Task.query.filter_by(name=u'Item Three').one() t4 = Task.query.filter_by(name=u'Item Four').one() t5 = Task.query.filter_by(name=u'Item Five').one() t6 = Task.query.filter_by(name=u'Item Six').one() t1.next_task = t5 t5.next_task = t2 t4.next_task = t6 Session.commit() Session.clear() print '-' * 80 task = Task.query.filter_by(name=u'Item One').one() while task is not None: print task task = task.next_task print '-' * 80 print '-' * 80 task = Task.query.filter_by(name=u'Item Six').one() while task is not None: print task task = task.previous_task print '-' * 80 -------------------------------------------------------------------- -- Jonathan LaCour http://cleverdevil.org --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---