:meth:`.Query.select_from` has been called, a warning is emitted.
As of 1.0.0b5 this will raise an error.
+ .. change::
+ :tags: bug, orm
+ :tickets: 3352
+ :versions: 1.0.0b5
+
+ Fixed bug where the state tracking within multiple, nested
+ :meth:`.Session.begin_nested` operations would fail to propagate
+ the "dirty" flag for an object that had been updated within
+ the inner savepoint, such that if the enclosing savepoint were
+ rolled back, the object would not be part of the state that was
+ expired and therefore reverted to its database state.
+
.. change::
:tags: bug, mysql, pymysql
:tickets: 3337
self._deleted.clear()
elif self.nested:
self._parent._new.update(self._new)
+ self._parent._dirty.update(self._dirty)
self._parent._deleted.update(self._deleted)
self._parent._key_switches.update(self._key_switches)
assert session.connection().execute(
'select count(1) from users').scalar() == 2
+ @testing.requires.savepoints
+ def test_dirty_state_transferred_deep_nesting(self):
+ User, users = self.classes.User, self.tables.users
+
+ mapper(User, users)
+
+ s = Session(testing.db)
+ u1 = User(name='u1')
+ s.add(u1)
+ s.commit()
+
+ nt1 = s.begin_nested()
+ nt2 = s.begin_nested()
+ u1.name = 'u2'
+ assert attributes.instance_state(u1) not in nt2._dirty
+ assert attributes.instance_state(u1) not in nt1._dirty
+ s.flush()
+ assert attributes.instance_state(u1) in nt2._dirty
+ assert attributes.instance_state(u1) not in nt1._dirty
+
+ s.commit()
+ assert attributes.instance_state(u1) in nt2._dirty
+ assert attributes.instance_state(u1) in nt1._dirty
+
+ s.rollback()
+ assert attributes.instance_state(u1).expired
+ eq_(u1.name, 'u1')
+
@testing.requires.independent_connections
def test_transactions_isolated(self):
User, users = self.classes.User, self.tables.users