Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
            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)
Ejemplo n.º 3
0
            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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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], ()))
Ejemplo n.º 6
0
    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], []))
Ejemplo n.º 7
0
                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)
Ejemplo n.º 8
0
                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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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]))
Ejemplo n.º 11
0
    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], [], []))