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.