hey there -
update and try it again. the fix i made for you yesterday was
slightly incorrect. youll notice that the dependency graph produced
for the second commit is much smaller after you update this change.
when you have the TEST_SELFREF turned on, even though theres no
actual parent/child relationships between C1 objects, the UOW still
treats it as though there may be some, so it breaks up C1's UOWTask
into a graph of per-object UOWTasks. Then, it was taking the list
of "save C2's" and sticking it as a dependency on each UOWTask,
instead of just attaching it as a dependency on the overall group of
C1's, causing it to save the list of C2's over and over again (except
it bails on the first element of the list on the second run, so you
dont see that unless you look at the dumped graph).
still working on making those graphs easier to read and considering
some simplifications i might make to the circular dependency thing.
On Jan 20, 2006, at 9:09 PM, [EMAIL PROTECTED] wrote:
On Jan 20, 2006, at 5:36 PM, Michael Bayer wrote:
Also, if you want to gain some understanding of objectstore, which
would be helpful if you have any ideas to offer, i just committed
a nicer "dependency dump" function. If you turn on
sqlalchemy.mapping.objectstore.LOG = True , youll see a "task
dump" in your standard out that looks like this (if you run
examples/adjacencytree/byroot_tree.py) :
hi mike,
thanks for your detailed response.
i haven't digested everything yet,
but have encountered another problem.
the code which causes the problem is below.
the basic problem is that the objectstore
will try to execute two identical INSERTs
and hence get a PK unique error.
one thing to note here is that the
entered data doesn't actually have
any reference cycles - the
table definition provides only the
possibility of there being a self-ref.
in addition, in you set TEST_SELFREF
to False, the problem does not arise.
i've been putting in a bunch of
'print's in objectstore.py in order
to trace this.
in this case, the (possible) problem
seems to be that a PropHistory ends
up inside a UOWTransaction.saved_lists,
and hence the:
del self.uow.modified_lists[obj]
in UOWTransaction.post_exec() raises
a KeyError.
this causes the uow to not flush
the saved entries properly, causing
the next invocation of .commit()
to try a duplicate INSERT. (or at
least that's what i think is going
on).
i inspected via pdb and found that
self.uow.modified_lists contains a
vanilla 'C2' object only. basically
what i did was:
---
for obj in self.saved_lists:
print 'POST_EXEC saved_lists', obj
try:
obj.commit()
del self.uow.modified_lists[obj]
except KeyError:
print 'post_exec lists keyerror'
import pdb
pdb.set_trace()
pass
---
i then tried to infer how the PropHistory
got entered into the saved_lists by doing:
---
def register_saved_list(self, listobj):
if isinstance(listobj, attributes.PropHistory):
import pdb
pdb.set_trace()
self.saved_lists.append(listobj)
---
but i don't really grok whether listobj
is supposed to be a list of objs so i
wasn't sure what to fix (or whether i'm
honing in on the actual problem).
i did notice that the PropHistory in
this case has a .obj attribute that in
fact seems to be the 'C2' object instance
that should be deleted from modified_lists,
but hesitated because of my lack of
understanding.
as always, if you have any thoughts
they'd be greatly appreciated.
thanks, d
(the actual code that breaks follows)
---
import sqlalchemy as rdb
TEST_SELFREF = True
rdb.mapping.objectstore.LOG = True
# Setup data
engine = rdb.create_engine('sqlite://', echo=True)
t1 = rdb.Table(
't1', engine,
rdb.Column('id', rdb.Integer, primary_key=True),
rdb.Column('selfref_id', rdb.Integer, rdb.ForeignKey('t1.id')),
)
t1.create()
class C1(object):
pass
m1 = rdb.mapper(C1, t1)
if TEST_SELFREF:
m1.add_property(
'selfref',
rdb.relation(C1, primaryjoin=(t1.c.id==t1.c.selfref_id),
foreignkey=t1.c.id))
t2 = rdb.Table(
't2', engine,
rdb.Column('id', rdb.Integer, primary_key=True),
rdb.Column('t1id', rdb.Integer, rdb.ForeignKey(t1.c.id)),
)
t2.create()
class C2(object):
pass
m2 = rdb.mapper(C2, t2)
m2.add_property(
't1', rdb.relation(m1, backref='t2s')
)
# Test
import itertools
idgen = itertools.count()
for i in xrange(10):
a1 = C1()
a1.id = idgen.next()
rdb.objectstore.commit()
for a1 in m1.select():
a2 = C2()
a2.id = idgen.next()
a2.t1 = a1
rdb.objectstore.commit()
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through
log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD
SPLUNK!
http://sel.as-us.falkag.net/sel?
cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users