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.