On Oct 25, 2010, at 1:07 PM, Lenza McElrath wrote:

> I am running into a issue where it looks like SQLAlchemy is not performing 
> the proper DB update when committing a session after modifying an object.  
> This happens only when all references to the updated object are lost, and I 
> update a mutable attribute BEFORE updating another attribute.  It seems as if 
> MutableAttrInstanceState.__resurrect is not properly resurrecting the object 
> state.
> 
> I have code that basically looks like this:
> 
> def update_my_model(session, my_model_id):
>     my_model = session.query(MyModel, id=my_model_id).one()
>     my_model.mutable_attribute.mutate()
>     my_model.normal_attribute = 42
>     return my_model
> 
> session = self.logic.session_maker()
> update_my_model(session, my_model_id)
> session.commit()
> 
> The above code does issues the SQL to update mutable_attribute, but not 
> normal_attribute.  Everything works if I move the mutable_attribute change to 
> after the normal_attribute change, remove it completely, or assign the return 
> value of the update_my_model call to a variable.
> 
> I have been able to determine that in that case that fails (and only in that 
> case) MutableAttrInstanceState._cleanup is being called as update_my_model 
> returns.  However, during the session.commit(), the call to 
> self.manager.new_instance(state=self) in MutableAttrInstanceState.__resurrect 
> is not returning an object that has normal_attribute set.  From what I can 
> tell the MutableAttrInstanceState instance should know about the update to 
> normal_attribute (InstanceState.modified_event is being called when it is 
> set).  But I'm not sure of the inner-workings of MutableAttrInstanceState,so 
> I haven't been able to confirm this.

What is not explained here is how the reference would be lost in the first 
place.   The change to my_model.normal_attribute would place the object in the 
session's "dirty" list which results in a strong reference being created from 
the state to the object, which in turn is strongly referenced by the Session's 
identity map.  


> 
> My mutable_attribute is rather complex, so it is entirely possible that it is 
> behaving badly in some why.  However, this seems like a strange failure mode 
> for an issue with that attribute?  Anyone have ideas on what is going on 
> here, or what my next steps should be to track it down?  If any information I 
> have not provided would be helpful, please let me know.

oh well definitely, try to create a simple test case.   For example, if I were 
to just take code like the above with a generic model, does that reproduce the 
issue ?    If you think something about your mutable attribute is at fault, try 
replacing it with a plain dictionary and change a value within.   I can't 
really imagine how anything regarding your mutable type could be involved 
unless it reaches out and modifies the environment containing "my_model" 
somehow.

If just the code above, I'd do things like:

def update_my_model(session, my_model_id):
    my_model = session.query(MyModel, id=my_model_id).one()
    my_model.mutable_attribute.mutate()
    assert my_model in session
    my_model.normal_attribute = 42
    assert my_model in session.dirty
    return my_model





-- 
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