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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---