Mutable fails to track changes in certain conditions
Hello, this is a code that illustrates my problem:
>>> product.attrdata
{'key': 1}
>>> product.attrdata = product.attrdata or {}
>>> product.attrdata['key'] = 20
>>> db_session.commit()
>>> db_session.refresh(product)
>>> product.attrdata
{'key': 1}
>>> product.attrdata['key'] = 20
>>> db_session.commit()
>>> db_session.refresh(product)
>>> product.attrdata
{'key': 20}
product.attrdata
is a MutableDict. As a first step, I've found that Mutable.changed()
fails:
def changed(self):
for parent, key in self._parents.items():
flag_modified(parent, key)
Because self._parents
are empty. That's because in MutableBase.set()
, when I do product.attrdata = product.attrdata
:
def set(target, value, oldvalue, initiator):
if not isinstance(value, cls):
value = cls.coerce(key, value)
if value is not None:
value._parents[target.obj()] = key
if isinstance(oldvalue, cls):
oldvalue._parents.pop(target.obj(), None)
return value
value is oldvalue
and parent gets popped after it was set. If I switch these two if's, then Mutable.changed()
will call flag_modified()
, but it won't flag properly it anyway (I didn't dig much further and don't have a patch to fix a problem).
Is it a bug or I shouldn't do things like product.attrdata = product.attrdata
in the first place?
SQLAlchemy version 0.9.3
Comments (6)
-
repo owner -
reporter Yes, I think so.
-
repo owner - changed status to resolved
- Fixed bug in mutable extension as well as
:func:
.attributes.flag_modified
where the change event would not be propagated if the attribute had been reassigned to itself. fixes#2997
→ <<cset b9a2b58dd747>>
-
repo owner - Fixed bug in mutable extension as well as
:func:
.attributes.flag_modified
where the change event would not be propagated if the attribute had been reassigned to itself. fixes#2997
Conflicts: lib/sqlalchemy/orm/state.py test/orm/test_attributes.py
→ <<cset 66d090be9cf0>>
- Fixed bug in mutable extension as well as
:func:
-
repo owner this is in 0.8 also. needed a little more than just that one change (was actually two bugs).
-
reporter Thank you a lot! When it's reasonable to expect a new version?
- Log in to comment
ok it seems like if set() just does "if value is oldvalue: return" that would fix it right?