summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-07-10 21:09:26 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-07-10 21:09:26 +0000
commit9b1b4e0cc09b7033e8ce0852567312a279c50b9b (patch)
tree3a8c57984fc61482a8e8727c4fa745541a3460c5
parent0c64a8ab5c05eb830f40980ded7fab541b1ca932 (diff)
downloadsqlalchemy-9b1b4e0cc09b7033e8ce0852567312a279c50b9b.tar.gz
further refinements to the previous session.expunge() fix
-rw-r--r--lib/sqlalchemy/orm/session.py16
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py2
-rw-r--r--test/orm/session.py15
3 files changed, 21 insertions, 12 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index ddf7d6251..15e422eec 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 5f28d28e7..c6b0b2689 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 d659d834b..7e0229a7c 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)