Beispiel #1
0
    def test_partially_mapped_inheritance(self):
        class A(object):
            pass

        class B(A):
            pass

        class C(B):
            def __init__(self, x):
                pass

        m = mapper(A, self.fixture())

        a = attributes.instance_state(A())
        assert isinstance(a, attributes.InstanceState)
        assert type(a) is not attributes.InstanceState

        b = attributes.instance_state(B())
        assert isinstance(b, attributes.InstanceState)
        assert type(b) is not attributes.InstanceState

        # B is not mapped in the current implementation
        self.assertRaises(sa.orm.exc.UnmappedClassError, class_mapper, B)

        # the constructor of C is decorated too.  
        # we don't support unmapped subclasses in any case,
        # users should not be expecting any particular behavior
        # from this scenario.
        c = attributes.instance_state(C(3))
        assert isinstance(c, attributes.InstanceState)
        assert type(c) is not attributes.InstanceState

        # C is not mapped in the current implementation
        self.assertRaises(sa.orm.exc.UnmappedClassError, class_mapper, C)
Beispiel #2
0
    def test_partially_mapped_inheritance(self):
        class A(object):
            pass

        class B(A):
            pass

        class C(B):
            def __init__(self):
                pass

        mapper(A, self.fixture())

        a = attributes.instance_state(A())
        assert isinstance(a, attributes.InstanceState)
        assert type(a) is not attributes.InstanceState

        b = attributes.instance_state(B())
        assert isinstance(b, attributes.InstanceState)
        assert type(b) is not attributes.InstanceState

        # C is unmanaged
        cobj = C()
        self.assertRaises((AttributeError, TypeError),
                          attributes.instance_state, cobj)
Beispiel #3
0
    def test_expire_cascade(self):
        mapper(User, users, properties={
            'addresses':relation(Address, cascade="all, refresh-expire")
        })
        mapper(Address, addresses)
        s = create_session()
        u = s.query(User).get(8)
        assert u.addresses[0].email_address == '*****@*****.**'

        u.addresses[0].email_address = 'someotheraddress'
        s.expire(u)
        u.name
        print attributes.instance_state(u).dict
        assert u.addresses[0].email_address == '*****@*****.**'
Beispiel #4
0
    def test_partial_expire(self):
        mapper(Order, orders)

        sess = create_session()
        o = sess.query(Order).get(3)

        sess.expire(o, attribute_names=['description'])
        assert 'id' in o.__dict__
        assert 'description' not in o.__dict__
        assert attributes.instance_state(o).dict['isopen'] == 1

        orders.update(orders.c.id == 3).execute(description='order 3 modified')

        def go():
            assert o.description == 'order 3 modified'

        self.assert_sql_count(testing.db, go, 1)
        assert attributes.instance_state(
            o).dict['description'] == 'order 3 modified'

        o.isopen = 5
        sess.expire(o, attribute_names=['description'])
        assert 'id' in o.__dict__
        assert 'description' not in o.__dict__
        assert o.__dict__['isopen'] == 5
        assert attributes.instance_state(o).committed_state['isopen'] == 1

        def go():
            assert o.description == 'order 3 modified'

        self.assert_sql_count(testing.db, go, 1)
        assert o.__dict__['isopen'] == 5
        assert attributes.instance_state(
            o).dict['description'] == 'order 3 modified'
        assert attributes.instance_state(o).committed_state['isopen'] == 1

        sess.flush()

        sess.expire(o, attribute_names=['id', 'isopen', 'description'])
        assert 'id' not in o.__dict__
        assert 'isopen' not in o.__dict__
        assert 'description' not in o.__dict__

        def go():
            assert o.description == 'order 3 modified'
            assert o.id == 3
            assert o.isopen == 5

        self.assert_sql_count(testing.db, go, 1)
Beispiel #5
0
    def test_basic(self):
        class A(_fixtures.Base):
            pass
        class B(_fixtures.Base):
            pass

        mapper(A, table_a, properties={
            'bs':relation(B, cascade="all, delete-orphan")
            })
        mapper(B, table_b)

        a1 = A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')])

        sess = create_session()
        sess.add(a1)
        sess.flush()

        sess.clear()

        eq_(sess.query(A).get(a1.id),
            A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')]))

        a1 = sess.query(A).get(a1.id)
        assert not class_mapper(B)._is_orphan(
            attributes.instance_state(a1.bs[0]))
        a1.bs[0].foo='b2modified'
        a1.bs[1].foo='b3modified'
        sess.flush()

        sess.clear()
        eq_(sess.query(A).get(a1.id),
            A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')]))
Beispiel #6
0
    def test_basic(self):
        class A(_fixtures.Base):
            pass

        class B(_fixtures.Base):
            pass

        mapper(A, table_a, properties={"bs": relation(B, cascade="all, delete-orphan")})
        mapper(B, table_b)

        a1 = A(name="a1", bs=[B(name="b1"), B(name="b2"), B(name="b3")])

        sess = create_session()
        sess.add(a1)
        sess.flush()

        sess.expunge_all()

        eq_(sess.query(A).get(a1.id), A(name="a1", bs=[B(name="b1"), B(name="b2"), B(name="b3")]))

        a1 = sess.query(A).get(a1.id)
        assert not class_mapper(B)._is_orphan(attributes.instance_state(a1.bs[0]))
        a1.bs[0].foo = "b2modified"
        a1.bs[1].foo = "b3modified"
        sess.flush()

        sess.expunge_all()
        eq_(sess.query(A).get(a1.id), A(name="a1", bs=[B(name="b1"), B(name="b2"), B(name="b3")]))
Beispiel #7
0
    def test_expire_cascade(self):
        mapper(User,
               users,
               properties={
                   'addresses': relation(Address,
                                         cascade="all, refresh-expire")
               })
        mapper(Address, addresses)
        s = create_session()
        u = s.query(User).get(8)
        assert u.addresses[0].email_address == '*****@*****.**'

        u.addresses[0].email_address = 'someotheraddress'
        s.expire(u)
        u.name
        print attributes.instance_state(u).dict
        assert u.addresses[0].email_address == '*****@*****.**'
Beispiel #8
0
    def test_partial_expire(self):
        mapper(Order, orders)

        sess = create_session()
        o = sess.query(Order).get(3)

        sess.expire(o, attribute_names=['description'])
        assert 'id' in o.__dict__
        assert 'description' not in o.__dict__
        assert attributes.instance_state(o).dict['isopen'] == 1

        orders.update(orders.c.id==3).execute(description='order 3 modified')

        def go():
            assert o.description == 'order 3 modified'
        self.assert_sql_count(testing.db, go, 1)
        assert attributes.instance_state(o).dict['description'] == 'order 3 modified'

        o.isopen = 5
        sess.expire(o, attribute_names=['description'])
        assert 'id' in o.__dict__
        assert 'description' not in o.__dict__
        assert o.__dict__['isopen'] == 5
        assert attributes.instance_state(o).committed_state['isopen'] == 1

        def go():
            assert o.description == 'order 3 modified'
        self.assert_sql_count(testing.db, go, 1)
        assert o.__dict__['isopen'] == 5
        assert attributes.instance_state(o).dict['description'] == 'order 3 modified'
        assert attributes.instance_state(o).committed_state['isopen'] == 1

        sess.flush()

        sess.expire(o, attribute_names=['id', 'isopen', 'description'])
        assert 'id' not in o.__dict__
        assert 'isopen' not in o.__dict__
        assert 'description' not in o.__dict__
        def go():
            assert o.description == 'order 3 modified'
            assert o.id == 3
            assert o.isopen == 5
        self.assert_sql_count(testing.db, go, 1)
Beispiel #9
0
    def __eq__(self, other):
        """'passively' compare this object to another.

        only look at attributes that are present on the source object.

        """

        if self in _recursion_stack:
            return True
        _recursion_stack.add(self)
        try:
            # pick the entity thats not SA persisted as the source
            try:
                state = attributes.instance_state(self)
                key = state.key
            except (KeyError, AttributeError):
                key = None
            if other is None:
                a = self
                b = other
            elif key is not None:
                a = other
                b = self
            else:
                a = self
                b = other

            for attr in a.__dict__.keys():
                if attr[0] == '_':
                    continue
                value = getattr(a, attr)
                #print "looking at attr:", attr, "start value:", value
                if hasattr(value,
                           '__iter__') and not isinstance(value, basestring):
                    try:
                        # catch AttributeError so that lazy loaders trigger
                        battr = getattr(b, attr)
                    except AttributeError:
                        #print "b class does not have attribute named '%s'" % attr
                        #raise
                        return False

                    if list(value) == list(battr):
                        continue
                    else:
                        return False
                else:
                    if value is not None:
                        if value != getattr(b, attr, None):
                            #print "2. Attribute named '%s' does not match that of b" % attr
                            return False
            else:
                return True
        finally:
            _recursion_stack.remove(self)
Beispiel #10
0
    def __eq__(self, other):
        """'passively' compare this object to another.

        only look at attributes that are present on the source object.

        """

        if self in _recursion_stack:
            return True
        _recursion_stack.add(self)
        try:
            # pick the entity thats not SA persisted as the source
            try:
                state = attributes.instance_state(self)
                key = state.key
            except (KeyError, AttributeError):
                key = None
            if other is None:
                a = self
                b = other
            elif key is not None:
                a = other
                b = self
            else:
                a = self
                b = other

            for attr in a.__dict__.keys():
                if attr[0] == '_':
                    continue
                value = getattr(a, attr)
                #print "looking at attr:", attr, "start value:", value
                if hasattr(value, '__iter__') and not isinstance(value, basestring):
                    try:
                        # catch AttributeError so that lazy loaders trigger
                        battr = getattr(b, attr)
                    except AttributeError:
                        #print "b class does not have attribute named '%s'" % attr
                        #raise
                        return False

                    if list(value) == list(battr):
                        continue
                    else:
                        return False
                else:
                    if value is not None:
                        if value != getattr(b, attr, None):
                            #print "2. Attribute named '%s' does not match that of b" % attr
                            return False
            else:
                return True
        finally:
            _recursion_stack.remove(self)
Beispiel #11
0
    def test_expire(self):
        mapper(User,
               users,
               properties={
                   'addresses': relation(Address, backref='user'),
               })
        mapper(Address, addresses)

        sess = create_session()
        u = sess.query(User).get(7)
        assert len(u.addresses) == 1
        u.name = 'foo'
        del u.addresses[0]
        sess.expire(u)

        assert 'name' not in u.__dict__

        def go():
            assert u.name == 'jack'

        self.assert_sql_count(testing.db, go, 1)
        assert 'name' in u.__dict__

        u.name = 'foo'
        sess.flush()
        # change the value in the DB
        users.update(users.c.id == 7, values=dict(name='jack')).execute()
        sess.expire(u)
        # object isnt refreshed yet, using dict to bypass trigger
        assert u.__dict__.get('name') != 'jack'
        assert 'name' in attributes.instance_state(u).expired_attributes

        sess.query(User).all()
        # test that it refreshed
        assert u.__dict__['name'] == 'jack'
        assert 'name' not in attributes.instance_state(u).expired_attributes

        def go():
            assert u.name == 'jack'

        self.assert_sql_count(testing.db, go, 0)
Beispiel #12
0
    def test_rebuild_state(self):
        """not much of a 'test', but illustrate how to 
        remove instance-level state before pickling.
        
        """
        mapper(User, users)

        u1 = User()
        attributes.manager_of_class(User).teardown_instance(u1)
        assert not u1.__dict__
        u2 = pickle.loads(pickle.dumps(u1))
        attributes.manager_of_class(User).setup_instance(u2)
        assert attributes.instance_state(u2)
Beispiel #13
0
    def test_expire_committed(self):
        """test that the committed state of the attribute receives the most recent DB data"""
        mapper(Order, orders)

        sess = create_session()
        o = sess.query(Order).get(3)
        sess.expire(o)

        orders.update(id=3).execute(description='order 3 modified')
        assert o.isopen == 1
        assert attributes.instance_state(o).dict['description'] == 'order 3 modified'
        def go():
            sess.flush()
        self.assert_sql_count(testing.db, go, 0)
Beispiel #14
0
    def test_expire(self):
        mapper(User, users, properties={
            'addresses':relation(Address, backref='user'),
            })
        mapper(Address, addresses)

        sess = create_session()
        u = sess.query(User).get(7)
        assert len(u.addresses) == 1
        u.name = 'foo'
        del u.addresses[0]
        sess.expire(u)

        assert 'name' not in u.__dict__

        def go():
            assert u.name == 'jack'
        self.assert_sql_count(testing.db, go, 1)
        assert 'name' in u.__dict__

        u.name = 'foo'
        sess.flush()
        # change the value in the DB
        users.update(users.c.id==7, values=dict(name='jack')).execute()
        sess.expire(u)
        # object isnt refreshed yet, using dict to bypass trigger
        assert u.__dict__.get('name') != 'jack'
        assert 'name' in attributes.instance_state(u).expired_attributes

        sess.query(User).all()
        # test that it refreshed
        assert u.__dict__['name'] == 'jack'
        assert 'name' not in attributes.instance_state(u).expired_attributes

        def go():
            assert u.name == 'jack'
        self.assert_sql_count(testing.db, go, 0)
Beispiel #15
0
    def test_no_instance_key(self):
        # this tests an artificial condition such that
        # an instance is pending, but has expired attributes.  this
        # is actually part of a larger behavior when postfetch needs to
        # occur during a flush() on an instance that was just inserted
        mapper(User, users)
        sess = create_session()
        u = sess.query(User).get(7)

        sess.expire(u, attribute_names=['name'])
        sess.expunge(u)
        attributes.instance_state(u).key = None
        assert 'name' not in u.__dict__
        sess.add(u)
        assert u.name == 'jack'
Beispiel #16
0
    def test_partially_mapped_inheritance(self):
        class A(object):
            pass

        class B(A):
            pass

        class C(B):
            def __init__(self):
                pass

        mapper(A, self.fixture())

        a = attributes.instance_state(A())
        assert isinstance(a, attributes.InstanceState)
        assert type(a) is not attributes.InstanceState

        b = attributes.instance_state(B())
        assert isinstance(b, attributes.InstanceState)
        assert type(b) is not attributes.InstanceState

        # C is unmanaged
        cobj = C()
        self.assertRaises((AttributeError, TypeError), attributes.instance_state, cobj)
Beispiel #17
0
    def test_no_instance_key(self):
        # this tests an artificial condition such that
        # an instance is pending, but has expired attributes.  this
        # is actually part of a larger behavior when postfetch needs to
        # occur during a flush() on an instance that was just inserted
        mapper(User, users)
        sess = create_session()
        u = sess.query(User).get(7)

        sess.expire(u, attribute_names=['name'])
        sess.expunge(u)
        attributes.instance_state(u).key = None
        assert 'name' not in u.__dict__
        sess.add(u)
        assert u.name == 'jack'
Beispiel #18
0
    def test_expire_committed(self):
        """test that the committed state of the attribute receives the most recent DB data"""
        mapper(Order, orders)

        sess = create_session()
        o = sess.query(Order).get(3)
        sess.expire(o)

        orders.update(id=3).execute(description='order 3 modified')
        assert o.isopen == 1
        assert attributes.instance_state(
            o).dict['description'] == 'order 3 modified'

        def go():
            sess.flush()

        self.assert_sql_count(testing.db, go, 0)