diff options
| -rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 12 | ||||
| -rw-r--r-- | test/orm/test_attributes.py | 33 |
2 files changed, 45 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 7f722aa44..40a69d96a 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -1247,3 +1247,15 @@ def del_attribute(instance, key): state, dict_ = instance_state(instance), instance_dict(instance) state.manager[key].impl.delete(state, dict_) +def flag_modified(instance, key): + """Mark an attribute on an instance as 'modified'. + + This sets the 'modified' flag on the instance and + establishes an unconditional change event for the given attribute. + + """ + state, dict_ = instance_state(instance), instance_dict(instance) + impl = state.manager[key].impl + state.modified_event(dict_, impl, NO_VALUE) + +
\ No newline at end of file diff --git a/test/orm/test_attributes.py b/test/orm/test_attributes.py index 9bbfa98eb..30156bbb7 100644 --- a/test/orm/test_attributes.py +++ b/test/orm/test_attributes.py @@ -1123,7 +1123,40 @@ class HistoryTest(_base.ORMTest): attributes.instance_state(f).commit(attributes.instance_dict(f), ['someattr']) eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [{'foo':'old'}], ())) + def test_flag_modified(self): + class Foo(_base.BasicEntity): + pass + + instrumentation.register_class(Foo) + attributes.register_attribute(Foo, 'someattr', uselist=False, useobject=False) + + f = Foo() + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), (), ())) + + f.someattr = {'a':'b'} + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([{'a':'b'},], (), ())) + attributes.instance_state(f).commit_all(attributes.instance_dict(f)) + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [{'a':'b'},], ())) + + f.someattr['a'] = 'c' + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [{'a':'c'},], ())) + attributes.flag_modified(f, 'someattr') + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([{'a':'c'},], (), ())) + + f.someattr = ['a'] + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([['a']], (), ())) + attributes.instance_state(f).commit_all(attributes.instance_dict(f)) + + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [['a']], ())) + f.someattr[0] = 'b' + f.someattr.append('c') + + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [['b', 'c']], ())) + attributes.flag_modified(f, 'someattr') + + eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([['b', 'c']], (), ())) + def test_use_object(self): class Foo(_base.BasicEntity): pass |
