Martijn Faassen wrote: > > Hi there, > > I'm looking at the remove() method in > sqlalchemy.orm.identify.WeakInstanceDict, as this is where the assertion > error is raised. > > In the 'self' dictionary there is indeed an > sqlalchemy.orm.state.InstanceState object with under the key (it's the > only entry in the dictionary), but it's a different state object than > what is passed in as the 'state' parameter. This triggers the > AssertionError. > > This remove() call is triggered by a piece of code that has a comment > "primary key switch", in _register_newly_persistent in session.py. > > I wish we could figure out why you don't get it and I do...
OK the cause is that the a_editable and a_published objects aren't just changing their primary keys, one of them is *switching* to the primary key of the other. the combination of both of these activities is not a case that we've tested before. therefore a "dictionary ordering" type of situation is at fault here, based on which object it bookkeeps first. Usually my tests on a linux kernel vs. an OSX kernel bring these things up. so i can reproduce with this: Index: lib/sqlalchemy/orm/unitofwork.py =================================================================== --- lib/sqlalchemy/orm/unitofwork.py (revision 6289) +++ lib/sqlalchemy/orm/unitofwork.py (working copy) @@ -281,7 +281,7 @@ execute() method has succeeded and the transaction has been committed. """ - for elem in self.elements: + for elem in reversed(list(self.elements)): if elem.isdelete: self.session._remove_newly_deleted(elem.state) elif not elem.listonly: Index: MANIFEST.in =================================================================== or if I just reverse: a_editable.status = PUBLISHED a_published.status = ARCHIVED and a potential fix is this: Index: lib/sqlalchemy/orm/session.py =================================================================== --- lib/sqlalchemy/orm/session.py (revision 6289) +++ lib/sqlalchemy/orm/session.py (working copy) @@ -1018,7 +1018,7 @@ state.key = instance_key elif state.key != instance_key: # primary key switch - self.identity_map.remove(state) + self.identity_map.discard(state) state.key = instance_key self.identity_map.replace(state) Index: MANIFEST.in =================================================================== I guess the unit test for this would be, to do the operation in both ways so that the issue is indicated regardless of dictionary ordering. > > Regards, > > Martijn > > > > > --~--~---------~--~----~------------~-------~--~----~ 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 sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---