Thanks for the quick response Michael. I do not know why all references to the object are lost. Adding the asserts you suggested shows that the object is in the session and in the dirty list as expected.
I have been able to reproduce the issue with a simple test case. I have untangled it from my infrastructure as much as possible, but you will have to provide your own sessionmaker and BaseModel. Please let me know if you are able to reproduce with this: http://pastebin.com/pC45S59E Interestingly, if I run the test on an existing row (as opposed to creating the row in the test) the test passes. -Lenza On Mon, Oct 25, 2010 at 10:33 AM, Michael Bayer <[email protected]>wrote: > > 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 [email protected]. > To unsubscribe from this group, send email to > [email protected]<sqlalchemy%[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.
