From: Mike Bayer Date: Sat, 24 Feb 2007 21:58:38 +0000 (+0000) Subject: - added "refresh-expire" cascade [ticket:492] X-Git-Tag: rel_0_3_6~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=777037d46d57f853819e36aad5147a32e244b9cb;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - added "refresh-expire" cascade [ticket:492] --- diff --git a/CHANGES b/CHANGES index 2024e3a63e..440d91a4ee 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ worked anyway), but also query.selectfirst(), query.selectone() which will be used as is (i.e. no query is compiled). works similarly to sending the results to instances(). + - added "refresh-expire" cascade [ticket:492] 0.3.5 - sql: - the value of "case_sensitive" defaults to True now, regardless of the diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 4935b04819..231be29b8b 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -264,12 +264,16 @@ class Session(object): an attribute is next accessed, the session will reload all attributes on the instance from the database. """ + for c in [obj] + list(_object_mapper(obj).cascade_iterator('refresh-expire', obj)): + self._expire_impl(c) + + def _expire_impl(self, obj): self._validate_persistent(obj) def exp(): if self.query(obj.__class__)._get(obj._instance_key, reload=True) is None: raise exceptions.InvalidRequestError("Could not refresh instance '%s'" % repr(obj)) attribute_manager.trigger_history(obj, exp) - + def is_expired(self, obj, unexpire=False): """return True if the given object has been marked as expired.""" ret = attribute_manager.has_trigger(obj) diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 293ec03770..9de58ce310 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -16,8 +16,7 @@ class CascadeOptions(object): self.save_update = "save-update" in values or "all" in values self.merge = "merge" in values or "all" in values self.expunge = "expunge" in values or "all" in values - # refresh_expire not really implemented as of yet - #self.refresh_expire = "refresh-expire" in values or "all" in values + self.refresh_expire = "refresh-expire" in values or "all" in values for x in values: if x not in all_cascades: @@ -26,7 +25,7 @@ class CascadeOptions(object): def __contains__(self, item): return getattr(self, item.replace("-", "_"), False) def __repr__(self): - return "CascadeOptions(arg=%s)" % repr(",".join([x for x in ['delete', 'save_update', 'merge', 'expunge', 'delete_orphan'] if getattr(self, x, False) is True])) + return "CascadeOptions(arg=%s)" % repr(",".join([x for x in ['delete', 'save_update', 'merge', 'expunge', 'delete_orphan', 'refresh-expire'] if getattr(self, x, False) is True])) def polymorphic_union(table_map, typecolname, aliasname='p_union'): """create a UNION statement used by a polymorphic mapper. diff --git a/test/orm/mapper.py b/test/orm/mapper.py index 414aaf378b..d8c23e103a 100644 --- a/test/orm/mapper.py +++ b/test/orm/mapper.py @@ -114,6 +114,14 @@ class MapperTest(MapperSuperTest): self.assert_(u.user_name == 'jack') self.assert_(a not in u.addresses) + def testexpirecascade(self): + mapper(User, users, properties={'addresses':relation(mapper(Address, addresses), cascade="all, refresh-expire")}) + s = create_session() + u = s.get(User, 8) + u.addresses[0].email_address = 'someotheraddress' + s.expire(u) + assert u.addresses[0].email_address == 'ed@wood.com' + def testrefreshwitheager(self): """test that a refresh/expire operation loads rows properly and sends correct "isnew" state to eager loaders""" mapper(User, users, properties={'addresses':relation(mapper(Address, addresses), lazy=False)})