Tefnet Developers wrote:
>
> 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.

flush what you need first.   then do things that are not compatible with
autoflush.

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

need you to attach the patch to an email or paste it elsewhere since
dpaste is down - it surprises me that all tests would pass since I recall
writing tests that were very sensitive to the order of events in those
methods, in particular that the events would fire off in such a way as to
prevent further steps from proceeding, then again it seems unusual that
modified_event() is called first, so perhaps the tests did not address
that aspect.

the patch also needs to be against trunk.   Before patching someone would
have to add some tests to at least test_attributes.py that exercise its
expected behavior.  I would also need to document within another test how
autoflush is being called from within modified_event().



> 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