On Jan 16, 2012, at 12:53 PM, Mariano Mara wrote:

> On 05.01.12 16:13, Michael Bayer wrote:
>> 
>> On Jan 5, 2012, at 3:03 PM, Mariano Mara wrote:
>> 
>>> Hi there! I have a master-detail entity. Since I do some post-processing 
>>> work
>>> on the details before inserting the entity in the db, I added an
>>> 'after_insert' event where I do the extra stuff.
>>> One of the things I need is to make sure certain "details" have been
>>> selected by the user and in case he didn't I add some default values on his
>>> behalf, just like
>>> 
>>>  master.detail.append(DetailCls(score=100, 
>>> timestamp=datetime.datetime.now()))
>> 
>> don't do any kind of manipulation of the flush plan, which includes 
>> collection alterations, inside of after_insert().   
>> 
>> The append() operation here is most cleanly implemented in the __init__ 
>> method of your Master object.  That way the model itself handles the shape 
>> it should be in.   
>> 
>> Another way to set up state is using the @validates hook to respond to an 
>> attribute set event:
>> 
>> http://www.sqlalchemy.org/docs/orm/mapper_config.html?highlight=validates#simple-validators
>> 
>> The other way is to use the before_flush event:
>> 
>> http://www.sqlalchemy.org/docs/orm/events.html?highlight=before_flush#sqlalchemy.orm.events.SessionEvents.before_flush
>> 
> 
> Thanks a lot for the answer. As expected adding my logic in the __init__ was
> the way to go. 
> I have a question though: 
> Let's say users can edit the detail instances of this master and in case I
> detect that certain attribute is modified, I want invalidate the detail and 
> create
> a new one. e.g.:
> 
> if get_history(inst_detail, "attr").has_changes():
>    inst_detail.active=False
>    new_detail = Detail(attr=new_attr, score=100)
>    master.append(new_detail)
> 
> My question is how I can skip the "attr" modification made in the 
> old_instance?
> I want to keep the active=False but I want to ignore the "attr" change. I
> tried with several methods in Session (e.g. expunge) but the update occurs
> nevertheless.

I think you'd want to expire inst_detail.active, like with Session.expire(), or 
you could also try attributes.set_committed_state(inst_detail, 'active', 
False), should erase the history.   

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@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