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#L475 
which 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.

Reply via email to