thanks for the quick reply! For now I have this working with the @property method. If we decide we really want to persist the derived attribute, we'll try doing an UPDATE inside the after_insert, as you suggest.
cheers, --Bill On Thu, Mar 29, 2012 at 5:38 PM, Michael Bayer <[email protected]>wrote: > auto increment happens right as the INSERT statement itself occurs - this > is within the flush well after any kind of attribute operations happen, and > also occurs outside of the realm of attribute events. > > The soonest you can get at this state is by using the after_insert event. > The after_flush and after_flush_postexec hooks could also be used. (the > ORM events are at : http://docs.sqlalchemy.org/en/latest/orm/events.html) > > As I often recommend, I will usually have attributes that are related to > another be lazily evaluated, rather than setting them actively. This > allows an attribute that's dependent on another to maintain the dependency > relationship, rather than having the source attribute be aware of > everywhere it needs to push out, such as: > > class MyClass(...): > @property > def some_derived_attribute(self): > return "Id: %d" % self.id > > Above uses @property but you can also use an approach like > @memoized_property at > http://www.sqlalchemy.org/trac/browser/lib/sqlalchemy/util/langhelpers.py#L475which > will evaluate the attribute only once. > > if the derived attribute here is actually persisted as part of the row, > then you may want to circumvent how the autoincrement is working. > Depending on which backend you're on, you can try executing a sequence to > get at a new PK ahead of time, or use triggers in your database. Or if > you're in the after_insert event, you could do an UPDATE for the row that > was just INSERTed. > > > > On Mar 29, 2012, at 7:43 PM, bill curtis wrote: > > > Hello! > > > > I have a model class Foo, with an auto-increment primary key. > > > > When the model added to the session and the session is flushed, the > primary key attribute becomes available as Foo.id. > > > > When Foo.id gets set by the ORM during the flush, I would like to trap > that, and set another attribute that is derived from the value of the id. > > > > I've tried doing this via the set() method on an AttributeExtension, and > also via an @validates decorator on the 'id' attribute. > > > > In both cases, I am getting into the set() method, or the @validates > method -- I can set a breakpoint and inspect the model object, and set the > value of the derived attribute -- but the derived value isn't readable > after I into my app from the flush call, and the derived value doesn't > persist. > > > > Does anyone know -- is there anyway to do what I'm trying to do? Do I > need to manually mark the derived attribute as dirty or something, inside > my set() or @validates method? > > > > thanks, > > --Bill > > > > -- > > 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. > > -- > 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. > > -- 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.
