Dnia 2009-10-19, pon o godzinie 18:20 -0400, Michael Bayer pisze: 
> you can disable the autoflush if you say
> query.autoflush(False).whatever().  I'd start there.

Well I need autoflush there to have current data.

> At the same time
> the AttributeExtensions are firing off in the middle of a sensitive
> section so some issues are unavoidable.

I made a patch which seems to solve the problem - moved modified_event()
calls in attributes.py after calls of AttributeExtensions methods.
After this change all sqlalchemy tests pass correctly.
I don't know sqlalchemy internals very well but it seems that
modified_event() somehow causes data flushed in extensions called after
it to take precedence over these set by the event itself.

(Copy at http://dpaste.com/115329/)
================================================================
Index: attributes.py
===================================================================
--- attributes.py (wersja 6463)
+++ attributes.py (kopia robocza)
@@ -429,10 +429,9 @@
         else:
             old = dict_.get(self.key, NO_VALUE)

-        state.modified_event(dict_, self, False, old)
-
         if self.extensions:
             self.fire_remove_event(state, dict_, old, None)
+        state.modified_event(dict_, self, False, old)
         del dict_[self.key]

     def get_history(self, state, dict_, passive=PASSIVE_OFF):
@@ -448,10 +447,9 @@
         else:
             old = dict_.get(self.key, NO_VALUE)

-        state.modified_event(dict_, self, False, old)
-
         if self.extensions:
             value = self.fire_replace_event(state, dict_, value, old,
initiator)
+        state.modified_event(dict_, self, False, old)
         dict_[self.key] = value

     def fire_replace_event(self, state, dict_, value, previous,
initiator):
@@ -518,14 +516,12 @@
         if initiator is self:
             return

-        state.modified_event(dict_, self, True, NEVER_SET)
-        
         if self.extensions:
             old = self.get(state, dict_)
             value = self.fire_replace_event(state, dict_, value, old,
initiator)
-            dict_[self.key] = value
-        else:
-            dict_[self.key] = value
+
+        state.modified_event(dict_, self, True, NEVER_SET)
+        dict_[self.key] = value
         state.mutable_dict[self.key] = value


@@ -591,17 +587,15 @@
         dict_[self.key] = value

     def fire_remove_event(self, state, dict_, value, initiator):
-        state.modified_event(dict_, self, False, value)
-
         if self.trackparent and value is not None:
             self.sethasparent(instance_state(value), False)

         for ext in self.extensions:
             ext.remove(state, value, initiator or self)

-    def fire_replace_event(self, state, dict_, value, previous,
initiator):
-        state.modified_event(dict_, self, False, previous)
+        state.modified_event(dict_, self, False, value)

+    def fire_replace_event(self, state, dict_, value, previous,
initiator):
         if self.trackparent:
             if previous is not value and previous is not None:
                 self.sethasparent(instance_state(previous), False)
@@ -609,6 +603,8 @@
         for ext in self.extensions:
             value = ext.set(state, value, previous, initiator or self)

+        state.modified_event(dict_, self, False, previous)
+
         if self.trackparent:
             if value is not None:
                 self.sethasparent(instance_state(value), True)
@@ -656,11 +652,11 @@
             return History.from_attribute(self, state, current)

     def fire_append_event(self, state, dict_, value, initiator):
-        state.modified_event(dict_, self, True, NEVER_SET,
passive=PASSIVE_NO_INITIALIZE)
-
         for ext in self.extensions:
             value = ext.append(state, value, initiator or self)

+ state.modified_event(dict_, self, True, NEVER_SET,
passive=PASSIVE_NO_INITIALIZE)
+
         if self.trackparent and value is not None:
             self.sethasparent(instance_state(value), True)

@@ -670,14 +666,14 @@
         state.modified_event(dict_, self, True, NEVER_SET,
passive=PASSIVE_NO_INITIALIZE)

     def fire_remove_event(self, state, dict_, value, initiator):
-        state.modified_event(dict_, self, True, NEVER_SET,
passive=PASSIVE_NO_INITIALIZE)
-
         if self.trackparent and value is not None:
             self.sethasparent(instance_state(value), False)

         for ext in self.extensions:
             ext.remove(state, value, initiator or self)

+        state.modified_event(dict_, self, True, NEVER_SET,
passive=PASSIVE_NO_INITIALIZE)
+
     def delete(self, state, dict_):
         if self.key not in dict_:
             return
================================================================


What do you think about it?

regards,
Filip Zyzniewski
Tefnet 


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

Reply via email to