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