On Oct 23, 2013, at 8:06 PM, Daniel Grace <thisgenericn...@gmail.com> wrote:

> I have a situation where an object in the ORM performs some calculations and 
> other assorted checks.  One of these situations is checking to see the 
> difference between the original value of an attribute and the current value 
> -- in particular, some of the validation going on should prohibit a change 
> that causes a particular check to fail, but only if that check wasn't already 
> failing (e.g. some legacy)
> 
> I see that I can use inspect() to get the history of attributes, but that 
> quickly gets unwieldy when working with a large number of attributes.  What 
> I'd love to be able to do is something like:
> 
> def do_something(self):
>     orig = get_original_version(self)
>     delta = self.value - orig.value
>     # ....
> 
> Is there a simple way to accomplish this?  Right now I'm doing something like:
> 
> orig_value, = inspect(self).attrs.value.history.non_added or (default_value, )
> 
> which seems messy and only works for scalar values.

a phrase like “unwieldy with a large number of attributes” doesn’t make sense 
to me, is this a collection of attributes in a list or something, in which case 
iterate through that list and call getattr(attrs, attrname).history?   if an 
API is verbose, just put a function around it that does what you need.  if as 
implied in the subject that some side effect is occurring that’s causing a 
flush to occur hence “losing changes”, probably run your operations within a 
session.no_autoflush: block 
(http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html?highlight=no_autoflush#sqlalchemy.orm.session.Session.no_autoflush).

history works for collections as well.   this is the fine grained API to get at 
attribute history before a flush and attrs supports iteration through all 
available attributes, so just use a loop like this:

def delta(obj):
    d = {}
    for attr in inspect(obj).attrs:
        if attr.history.has_changes():
            d[attr.key] = attr.history.added, attr.history.deleted
    return d

im not sure what exactly you’d like to see for collections, the above will just 
put a tuple of (things added), (things removed) for that entry in the 
dictionary.   



-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to