def merge(self, session, source, dest, dont_load, _recursive): if not dont_load and self._reverse_property and (source, self._reverse_property) in _recursive: return if not "merge" in self.cascade: dest._state.expire_attributes([self.key]) return instances = attributes.get_as_list(source._state, self.key, passive=True) if not instances: return if self.uselist: dest_list = [] for current in instances: _recursive[(current, self)] = True obj = session.merge(current, entity_name=self.mapper.entity_name, dont_load=dont_load, _recursive=_recursive) if obj is not None: dest_list.append(obj) if dont_load: coll = attributes.init_collection(dest, self.key) for c in dest_list: coll.append_without_event(c) else: getattr(dest.__class__, self.key).impl._set_iterable(dest._state, dest_list) else: current = instances[0] if current is not None: _recursive[(current, self)] = True obj = session.merge(current, entity_name=self.mapper.entity_name, dont_load=dont_load, _recursive=_recursive) if obj is not None: if dont_load: dest.__dict__[self.key] = obj else: setattr(dest, self.key, obj)
def execute(instance, row, isnew, **flags): decorated_row = row_decorator(row) if not self.uselist: if self._should_log_debug: self.logger.debug("eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key)) if isnew: # set a scalar object instance directly on the # parent object, bypassing InstrumentedAttribute # event handlers. # instance.__dict__[self.key] = self.mapper._instance(selectcontext, decorated_row, None) else: # call _instance on the row, even though the object has been created, # so that we further descend into properties self.mapper._instance(selectcontext, decorated_row, None) else: if isnew or self.key not in instance._state.appenders: # appender_key can be absent from selectcontext.attributes with isnew=False # when self-referential eager loading is used; the same instance may be present # in two distinct sets of result columns if self._should_log_debug: self.logger.debug("initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key)) collection = attributes.init_collection(instance, self.key) appender = util.UniqueAppender(collection, 'append_without_event') instance._state.appenders[self.key] = appender result_list = instance._state.appenders[self.key] if self._should_log_debug: self.logger.debug("eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key)) self.mapper._instance(selectcontext, decorated_row, result_list)
def test_object_collections_set(self): class Foo(_base.BasicEntity): pass class Bar(_base.BasicEntity): def __nonzero__(self): assert False attributes.register_class(Foo) attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True) hi = Bar(name='hi') there = Bar(name='there') old = Bar(name='old') new = Bar(name='new') # case 1. new object f = Foo() eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [], ())) f.someattr = [hi] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], [])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi], ())) f.someattr = [there] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([there], [], [hi])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [there], ())) f.someattr = [hi] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], [there])) f.someattr = [old, new] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old, new], [], [there])) # case 2. object with direct settings (similar to a load operation) f = Foo() collection = attributes.init_collection(attributes.instance_state(f), 'someattr') collection.append_without_event(new) attributes.instance_state(f).commit_all() eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [new], ())) f.someattr = [old] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old], [], [new])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [old], ()))
def test_object_collections_set(self): class Foo(fixtures.Base): pass class Bar(fixtures.Base): def __nonzero__(self): assert False attributes.register_class(Foo) attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True) hi = Bar(name='hi') there = Bar(name='there') old = Bar(name='old') new = Bar(name='new') # case 1. new object f = Foo() self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], [])) f.someattr = [hi] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi], [])) f.someattr = [there] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([there], [], [hi])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [there], [])) f.someattr = [hi] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [there])) f.someattr = [old, new] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old, new], [], [there])) # case 2. object with direct settings (similar to a load operation) f = Foo() collection = attributes.init_collection(f, 'someattr') collection.append_without_event(new) f._state.commit_all() self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new], [])) f.someattr = [old] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old], [], [new])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [old], []))
def execute(state, row, isnew, **flags): if isnew or (state, key) not in context.attributes: # appender_key can be absent from context.attributes with isnew=False # when self-referential eager loading is used; the same instance may be present # in two distinct sets of result columns collection = attributes.init_collection(state, key) appender = util.UniqueAppender(collection, 'append_without_event') context.attributes[(state, key)] = appender result_list = context.attributes[(state, key)] _instance(row, result_list)
def merge(self, session, source, dest, dont_load, _recursive): if not dont_load: # TODO: no test coverage for recursive check for r in self._reverse_property: if (source, r) in _recursive: return source_state = attributes.instance_state(source) dest_state = attributes.instance_state(dest) if not "merge" in self.cascade: dest_state.expire_attributes([self.key]) return instances = source_state.value_as_iterable(self.key, passive=True) if not instances: return if self.uselist: dest_list = [] for current in instances: _recursive[(current, self)] = True obj = session.merge(current, dont_load=dont_load, _recursive=_recursive) if obj is not None: dest_list.append(obj) if dont_load: coll = attributes.init_collection(dest_state, self.key) for c in dest_list: coll.append_without_event(c) else: getattr(dest.__class__, self.key).impl._set_iterable(dest_state, dest_list) else: current = instances[0] if current is not None: _recursive[(current, self)] = True obj = session.merge(current, dont_load=dont_load, _recursive=_recursive) if obj is not None: if dont_load: dest_state.dict[self.key] = obj else: setattr(dest, self.key, obj)
def test_object_collections_mutate(self): class Foo(_base.BasicEntity): pass class Bar(_base.BasicEntity): pass attributes.register_class(Foo) attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True) attributes.register_attribute(Foo, 'id', uselist=False, useobject=False) hi = Bar(name='hi') there = Bar(name='there') old = Bar(name='old') new = Bar(name='new') # case 1. new object f = Foo(id=1) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [], ())) f.someattr.append(hi) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], [])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi], ())) f.someattr.append(there) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([there], [hi], [])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi, there], ())) f.someattr.remove(there) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([], [hi], [there])) f.someattr.append(old) f.someattr.append(new) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old, new], [hi], [there])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi, old, new], ())) f.someattr.pop(0) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([], [old, new], [hi])) # case 2. object with direct settings (similar to a load operation) f = Foo() f.__dict__['id'] = 1 collection = attributes.init_collection(attributes.instance_state(f), 'someattr') collection.append_without_event(new) attributes.instance_state(f).commit_all() eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [new], ())) f.someattr.append(old) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old], [new], [])) attributes.instance_state(f).commit(['someattr']) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [new, old], ())) f = Foo() collection = attributes.init_collection(attributes.instance_state(f), 'someattr') collection.append_without_event(new) attributes.instance_state(f).commit_all() eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [new], ())) f.id = 1 f.someattr.remove(new) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([], [], [new])) # case 3. mixing appends with sets f = Foo() f.someattr.append(hi) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], [])) f.someattr.append(there) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi, there], [], [])) f.someattr = [there] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([there], [], [])) # case 4. ensure duplicates show up, order is maintained f = Foo() f.someattr.append(hi) f.someattr.append(there) f.someattr.append(hi) eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi, there, hi], [], [])) attributes.instance_state(f).commit_all() eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi, there, hi], ())) f.someattr = [] eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([], [], [hi, there, hi]))
def test_object_collections_mutate(self): class Foo(fixtures.Base): pass class Bar(fixtures.Base): pass attributes.register_class(Foo) attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True) attributes.register_attribute(Foo, 'id', uselist=False, useobject=False) hi = Bar(name='hi') there = Bar(name='there') old = Bar(name='old') new = Bar(name='new') # case 1. new object f = Foo(id=1) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], [])) f.someattr.append(hi) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi], [])) f.someattr.append(there) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([there], [hi], [])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi, there], [])) f.someattr.remove(there) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi], [there])) f.someattr.append(old) f.someattr.append(new) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old, new], [hi], [there])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi, old, new], [])) f.someattr.pop(0) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [old, new], [hi])) # case 2. object with direct settings (similar to a load operation) f = Foo() f.__dict__['id'] = 1 collection = attributes.init_collection(f, 'someattr') collection.append_without_event(new) f._state.commit_all() self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new], [])) f.someattr.append(old) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old], [new], [])) f._state.commit(['someattr']) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new, old], [])) f = Foo() collection = attributes.init_collection(f, 'someattr') collection.append_without_event(new) f._state.commit_all() self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new], [])) f.id = 1 f.someattr.remove(new) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], [new])) # case 3. mixing appends with sets f = Foo() f.someattr.append(hi) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [])) f.someattr.append(there) self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi, there], [], [])) f.someattr = [there] self.assertEquals(attributes.get_history(f._state, 'someattr'), ([there], [], []))