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

Reply via email to