yup, so what I can say is that this is one of the many fruits that await you 
when you get onto 0.7 :).    attribute stuff is very difficult to change in a 
maintenance release as every minute behavior affects all kinds of things.

The history of the attribute system is this:  the current idea came online 
around version 0.4, and in version 0.5 received a major overhaul.    The system 
was built strictly for usage by the unit of work system as an internal system.  
 Around the end of 0.5, or maybe in 0.6, the idea of making first the "events" 
provided by AttributeExtension public came along, and soon after that the idea 
of making the history system semi-public so that handy versioning extensions 
could be built.   The theme here is that the attribute history system as a 
public API is 100% an afterthought and was never its original purpose.   The 
mechanics of the UOW, lazy loading, etc. are all extremely intertwined with the 
smallest details of how the attribute system works, so it's hard to change.   
0.7 made the system a lot stronger (as did 0.6, 0.5, etc.) and it behaves much 
more nicely, but there's still lots of weird cases where it doesn't.   There's 
proposals in 0.8 to further refine its "public" behavior: see 
http://www.sqlalchemy.org/trac/ticket/2128 .   If you'd like to add suggestions 
to that, feel free.   It's a pretty complicated feature (as we have conditions 
like: attribute had no value at all, attribute might have had a value but we 
didn't load it, etc.)



On Sep 23, 2011, at 1:27 PM, Kent wrote:

> Sorry for not checking in the first place.  From the looks of this 0.7
> code and specifically from the comment, it seems you've already
> changed this:
> 
>    @classmethod
>    def from_scalar_attribute(cls, attribute, state, current):
>        original = state.committed_state.get(attribute.key,
> _NO_HISTORY)
> 
>        if original is _NO_HISTORY:
>            if current is NO_VALUE:
>                return cls((), (), ())
>            else:
>                return cls((), [current], ())
>        # dont let ClauseElement expressions here trip things up
>        elif attribute.is_equal(current, original) is True:
>            return cls((), [current], ())
>        else:
>            # current convention on native scalars is to not
>            # include information
>            # about missing previous value in "deleted", but
>            # we do include None, which helps in some primary
>            # key situations
>            if id(original) in _NO_STATE_SYMBOLS:
>                deleted = ()
>            else:
>                deleted = [original]
>            if current is NO_VALUE:
>                return cls((), (), deleted)
>            else:
>                return cls([current], (), deleted)
> 
> 
> 
> On Sep 23, 1:12 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
>> I can look later today, but what does 0.7 do?  
>> 
>> Sent from my iPhone
>> 
>> On Sep 23, 2011, at 11:17 AM, Kent <jkentbo...@gmail.com> wrote:
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>>> I see the code specifically treats going from None as deleted = ():
>>> 1417                else:
>>> 1418 ->                 if original is not None:
>>> 1419                        deleted = [original]
>>> 1420                    else:
>>> 1421                        deleted = ()
>>> 1422                    return cls([current], (), deleted)
>> 
>>> So I guess the question is why and is that inconsistent with going to
>>> None?
>> 
>>> On Sep 23, 10:39 am, Kent <jkentbo...@gmail.com> wrote:
>>>> I have two scalar columns in this example. (This is SQLAlchemy-0.6.4)
>> 
>>>> ========= To NULL ==============
>>>> print l.percentofsale1
>>>> 100
>> 
>>>> l.percentofsale1=None
>> 
>>>> attributes.get_history(l,'percentofsale1')
>>>> ([None], (), [Decimal('100')])
>> 
>>>> ========= From NULL ==============
>>>> print l.discount
>>>> None
>> 
>>>> l.discount=Decimal(100)
>> 
>>>> attributes.get_history(l,'discount')
>>>> ([Decimal('100')], (), ())
>> 
>>>> I expected to be able to see the history moving from None to
>>>> Decimal('100') like this:
>>>> ([Decimal('100')], (), [None])
>> 
>>>> Which would seem consistent with moving To NULL.  Why is the
>>>> history.deleted () instead of [None]?
>> 
>>>> Thanks,
>>>> Kent
>> 
>>> --
>>> 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 
>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
> 
> -- 
> 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.
> 

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