0.4.3
-----
- orm
- - Added very rudimentary yielding iterator behavior to Query. Call
- query.yield_per(<number of rows>) and evaluate the Query in an
+ - fixed fairly critical bug whereby the same instance could be listed
+ more than once in the unitofwork.new collection; most typically
+ reproduced when using a combination of inheriting mappers and
+ ScopedSession.mapper, as the multiple __init__ calls per instance
+ could save() the object with distinct _state objects
+
+ - added very rudimentary yielding iterator behavior to Query. Call
+ query.yield_per(<number of rows>) and evaluate the Query in an
iterative context; every collection of N rows will be packaged up
and yielded. Use this method with extreme caution since it does
not attempt to reconcile eagerly loaded collections across
doinit = False
def init(instance, *args, **kwargs):
- instance._state = InstanceState(instance)
+ if not hasattr(instance, '_state'):
+ instance._state = InstanceState(instance)
if extra_init:
extra_init(class_, oldinit, instance, args, kwargs)
assert x.element2 == 'this is the shared attr'
assert y.element2 == 'this is the shared attr'
+ def test_no_double_state(self):
+ states = set()
+ class Foo(object):
+ def __init__(self):
+ states.add(self._state)
+ class Bar(Foo):
+ def __init__(self):
+ states.add(self._state)
+ Foo.__init__(self)
+
+
+ attributes.register_class(Foo)
+ attributes.register_class(Bar)
+
+ b = Bar()
+ self.assertEquals(len(states), 1)
+ self.assertEquals(list(states)[0].obj(), b)
+
+
def test_inheritance2(self):
"""test that the attribute manager can properly traverse the managed attributes of an object,
if the object is of a descendant class with managed attributes in the parent class"""
u3 = sess.query(User).get(u1.user_id)
assert u3 is not u1 and u3 is not u2 and u3.user_name == u1.user_name
+ def test_no_double_save(self):
+ sess = create_session()
+ class Foo(object):
+ def __init__(self):
+ sess.save(self)
+ class Bar(Foo):
+ def __init__(self):
+ sess.save(self)
+ Foo.__init__(self)
+ mapper(Foo, users)
+ mapper(Bar, users)
+
+ b = Bar()
+ assert b in sess
+ assert len(list(sess)) == 1
+
+
class ScopedSessionTest(ORMTest):
def define_tables(self, metadata):
pass
Session.mapper(Baz, table2, extension=ext)
assert hasattr(Baz, 'query')
-
+
def test_validating_constructor(self):
s2 = SomeObject(someid=12)
s3 = SomeOtherObject(someid=123, bogus=345)