Re: [sqlalchemy] Re: SQLAlchemy not updating all expected columns after mutable attribute modification
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 mike...@zzzcomputing.comwrote: 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.comsqlalchemy%2bunsubscr...@googlegroups.com . 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 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.
Re: [sqlalchemy] Re: SQLAlchemy not updating all expected columns after mutable attribute modification
thanks, this is a simple issue that appears to be throughout the 0.6 series only, resolved in r26f423a667ca which you can get at http://hg.sqlalchemy.org/sqlalchemy/archive/26f423a667ca.tar.gz . On Oct 26, 2010, at 2:41 PM, Lenza McElrath wrote: 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 mike...@zzzcomputing.com 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 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. -- 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. -- You received this message because you are subscribed
[sqlalchemy] Re: SQLAlchemy not updating all expected columns after mutable attribute modification
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_modelreturns. 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. 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. Thanks for any help! -Lenza -- 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.
Re: [sqlalchemy] Re: SQLAlchemy not updating all expected columns after mutable attribute modification
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.