[Sqlalchemy-tickets] Issue #2997: Mutable fails to track changes in certain conditions (zzzeek/sqla
Brought to you by:
zzzeek
|
From: Vsevolod S. <iss...@bi...> - 2014-03-19 11:07:40
|
New issue 2997: Mutable fails to track changes in certain conditions https://bitbucket.org/zzzeek/sqlalchemy/issue/2997/mutable-fails-to-track-changes-in-certain Vsevolod Solovyov: Hello, this is a code that illustrates my problem: ``` #!python >>> 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: ``` #!python 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`: ``` #!python 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 |