From 9b1b4e0cc09b7033e8ce0852567312a279c50b9b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 10 Jul 2007 21:09:26 +0000 Subject: [PATCH] further refinements to the previous session.expunge() fix --- lib/sqlalchemy/orm/session.py | 16 +++++----------- lib/sqlalchemy/orm/unitofwork.py | 2 +- test/orm/session.py | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index ddf7d6251c..15e422eec1 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -380,10 +380,11 @@ class Session(object): Cascading will be applied according to the *expunge* cascade rule. """ - + self._validate_persistent(object) for c in [object] + list(_object_mapper(object).cascade_iterator('expunge', object)): - self.uow._remove_deleted(c) - self._unattach(c) + if c in self: + self.uow._remove_deleted(c) + self._unattach(c) def save(self, object, entity_name=None): """Add a transient (unsaved) instance to this ``Session``. @@ -615,16 +616,9 @@ class Session(object): obj._sa_session_id = self.hash_key def _unattach(self, obj): - self._validate_attached(obj) - del obj._sa_session_id - - def _validate_attached(self, obj): - """Validate that the given object is either pending or - persistent within this Session. - """ - if not self._is_attached(obj): raise exceptions.InvalidRequestError("Instance '%s' not attached to this Session" % repr(obj)) + del obj._sa_session_id def _validate_persistent(self, obj): """Validate that the given object is persistent within this diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 5f28d28e76..c6b0b2689c 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -108,7 +108,7 @@ class UnitOfWork(object): echo = logging.echo_property() def _remove_deleted(self, obj): - if hasattr(obj, "_instance_key") and obj._instance_key in self.identity_map: + if hasattr(obj, "_instance_key"): del self.identity_map[obj._instance_key] try: self.deleted.remove(obj) diff --git a/test/orm/session.py b/test/orm/session.py index d659d834bd..7e0229a7c8 100644 --- a/test/orm/session.py +++ b/test/orm/session.py @@ -38,6 +38,21 @@ class SessionTest(AssertMixin): s.user_name = 'some other user' s.flush() + def test_expunge_cascade(self): + tables.data() + mapper(Address, addresses) + mapper(User, users, properties={ + 'addresses':relation(Address, backref=backref("user", cascade="all"), cascade="all") + }) + session = create_session() + u = session.query(User).filter_by(user_id=7).one() + + # get everything to load in both directions + print [a.user for a in u.addresses] + + # then see if expunge fails + session.expunge(u) + def test_transaction(self): class User(object):pass mapper(User, users) -- 2.47.2