context.runid = _new_runid()
- filter_fns = [ent.filter_fn
- for ent in query._entities]
+ filter_fns = [ent.filter_fn for ent in query._entities]
filtered = id in filter_fns
single_entity = len(query._entities) == 1 and \
state.manager.dispatch.refresh(
state, context, only_load_props)
- if populate_existing:
+ if populate_existing or state.modified:
if refresh_state and only_load_props:
state._commit(dict_, only_load_props)
else:
if state in context.partials:
isnew = False
- (d_, attrs) = context.partials[state]
+ to_load = context.partials[state]
for key, populator in existing_populators:
- if key not in attrs:
+ if key not in to_load:
continue
populator(state, dict_, row)
else:
isnew = True
- attrs = unloaded
- context.partials[state] = (dict_, attrs)
+ to_load = unloaded
+ context.partials[state] = to_load
+
if context.propagate_options:
state.load_options = context.propagate_options
if state.load_options:
state.load_path = load_path
for key, populator in new_populators:
- if key not in attrs:
+ if key not in to_load:
continue
populator(state, dict_, row)
- state._commit(dict_, attrs)
-
for key, pop in eager_populators:
if key not in unloaded:
pop(state, dict_, row)
if isnew and refresh_evt:
- state.manager.dispatch.refresh(state, context, attrs)
+ state.manager.dispatch.refresh(state, context, to_load)
+
+ if isnew:
+ state._commit(dict_, to_load)
return instance
return _instance
sess.query(User).first()
eq_(canary, [])
+ def test_changes_reset(self):
+ """test the contract of load/refresh such that history is reset.
+
+ This has never been an official contract but we are testing it
+ here to ensure it is maintained given the loading performance
+ enhancements.
+
+ """
+ User = self.classes.User
+
+ @event.listens_for(User, "load")
+ def canary1(obj, context):
+ obj.name = 'new name!'
+
+ @event.listens_for(User, "refresh")
+ def canary2(obj, context, props):
+ obj.name = 'refreshed name!'
+
+ sess = Session()
+ u1 = User(name='u1')
+ sess.add(u1)
+ sess.commit()
+ sess.close()
+
+ u1 = sess.query(User).first()
+ eq_(
+ attributes.get_history(u1, "name"),
+ ((), ['new name!'], ())
+ )
+ assert "name" not in attributes.instance_state(u1).committed_state
+ assert u1 not in sess.dirty
+
+ sess.expire(u1)
+ u1.id
+ eq_(
+ attributes.get_history(u1, "name"),
+ ((), ['refreshed name!'], ())
+ )
+ assert "name" not in attributes.instance_state(u1).committed_state
+ assert u1 in sess.dirty
+
+
+
+
def test_repeated_rows(self):
User = self.classes.User