There might be a communication problem, which an example could help
clarify.

I'm constrained by a legacy database that I have no control over
changing.  When an order is changed, I need to calculate the change in
volume (or points) so I can update a table that records this
information.

Here is an example of a method you might want to run on an the
original, unchanged object (Order, in this case):
=================================================================
def calc_points(self):
    return sum(l.product.points * l.qtyordered for l in
self.orderdetails if l.product.points is not None)
=================================================================

Notice that this calculation relies on several relations:
orderdetails, and orderdetails[].product

>From an MVC view point, my argument is that certainly this business
logic *should* reside in the Order class.  That is to say, "an Order
should know how to calculate its own volume".

Unfortunately, this is not a matter of two or three *fields* that I
can easily extract from attributes.get_history().  This computation,
again, relies on several relations.

Any further insight or advice?




On Apr 29, 12:57 pm, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
> if you have a method like 'calculate_total_volume()', that is a business
> method.  you should not be relying upon the internals of the ORM to figure
> that out for you, and you should have two distinct fields on your object
> to represent the two values you need to make that calculation.
>
>
>
> Kent wrote:
> > That sounds like it could be very useful for me, thank you for
> > pointing me there.  That could solve one of the two issues I'm facing
> > that I listed... what about the other?
>
> > On Apr 29, 11:02 am, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
> >> Kent wrote:
> >> > Before saving objects to the database, we have need to inspect the
> >> > changes.  I am aware of the attributes.get_history() functionality,
> >> > which is helpful to a point.
>
> >> > attributes.get_history() falls short of what I need in two places:
> >> > *** after a session.flush(), it is gone.  There are times we need to
> >> > flush, but the transaction has still not been committed, and more
> >> > processing is required, so we still need access to the history of
> >> > changes for this object in this transaction despite a call to flush().
> >> > *** if there are calculation methods I've written that objects have, I
> >> > need to be able to call these for the "old" object.  For example, say
> >> > I write a method on Order class such as "def
> >> > calculate_total_volume(self):"  When an order is saved I need to
> >> > compare the old volume to the new.  On the merged order, I can call
> >> > "merged_obj.calculate_total_volume()", but I would need to use the
> >> > information in attributes.get_history() to *recreate* the "old"
> >> > version of the object in order to call
> >> > "old_order.calculate_total_volume()"
>
> >> > I've realized that if merge() attached a python attribute, such as
> >> > "_original" (which is a transient clone of the object fetched from the
> >> > database) to each object as it merges it, then this
> >> > * would be accessible regardless of session.flush()
> >> > * could be acted on with object methods like any other object
> >> > * is probably more intuitive than "attributes.get_history()",
> >> > especially to those familiar with Oracle triggers and :OLD.orderid
> >> > vs :NEW.orderid.  This would be very similar:   "merged.orderid" vs
> >> > "merged._original.orderid"
>
> >> > Disadvantage:
> >> > * it goes against the concept of trying to be very hands-off on the
> >> > actual object.  Maybe it could instead be stored in the instance's
> >> > state or something.
>
> >> > Does this conceptually make sense?  Does it make enough sense to make
> >> > this a feature?
>
> >> > In the meantime, can you recommend an approach for me?  (Extend the
> >> > Session class?)
>
> >> you want to be using a SessionExtension here, and the "after_flush()"
> >> hook
> >> is provided precisely for the use case that you want rules to execute
> >> after SQL has been flushed, but you still want a full accounting of
> >> everything that has changed - the attribute history on all objects has
> >> not
> >> yet been reset at this point.   The information available in
> >> after_flush()
> >> is unique in that it also includes any foreign key values that have been
> >> synchronized from parent to child over relationships.
>
> >> > Thanks much,
> >> > Kent
>
> >> > --
> >> > You received this message because you are subscribed to the Google
> >> Groups
> >> > "sqlalchemy" group.
> >> > To post to this group, send email to sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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