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

Reply via email to