this patch will cause the mapper to reload all the properties in identity-mapped objects every time a SELECT statement comes across it, blowing away any changes that might have been made to the object in memory. it maintains the unique per-session identity map of instances:

Index: lib/sqlalchemy/mapping/mapper.py
===================================================================
--- lib/sqlalchemy/mapping/mapper.py    (revision 1215)
+++ lib/sqlalchemy/mapping/mapper.py    (working copy)
@@ -308,6 +308,7 @@
         return self._get(key, ident)

     def _get(self, key, ident=None, reload=False):
+        reload = True
         if not reload:
             try:
                 return objectstore.get_session()._get(key)
@@ -815,6 +816,7 @@
# look in main identity map. if its there, we dont do anything to it, # including modifying any of its related items lists, as its already
         # been exposed to being modified by the application.
+        populate_existing = True
         identitykey = self._identity_key(row)
         sess = objectstore.get_session()
         if sess.has_key(identitykey):

Alternatively, this patch blows away the Identity Map entirely. this patch is the most equivalent to the feature youre looking for, i.e. disabling all "caching". definitely worth trying:

Index: lib/sqlalchemy/mapping/unitofwork.py
===================================================================
--- lib/sqlalchemy/mapping/unitofwork.py        (revision 1215)
+++ lib/sqlalchemy/mapping/unitofwork.py        (working copy)
@@ -70,6 +70,10 @@
     def create_list(self, obj, key, list_, **kwargs):
         return UOWListElement(obj, key, list_, **kwargs)
+
+class DoNothingDict(dict):
+    def __setitem__(self, key, value):
+        pass

class UnitOfWork(object):
"""main UOW object which stores lists of dirty/new/deleted objects, as well as 'modified_lists' for list attributes. provides top-level "commit" functionality as well as the transaction boundaries with the SQLEngine(s) involved in a write operation."""
@@ -77,7 +81,7 @@
         if identity_map is not None:
             self.identity_map = identity_map
         else:
-            self.identity_map = weakref.WeakValueDictionary()
+            self.identity_map = DoNothingDict()

         self.attributes = global_attributes
         self.new = util.HashSet(ordered = True)
@@ -142,8 +146,8 @@
     def _validate_obj(self, obj):
"""validates that dirty/delete/commit operations can occur upon the given object, by checking if it has an instance key and that the instance key is present in the identity map.""" - if hasattr(obj, '_instance_key') and not self.identity_map.has_key(obj._instance_key): - raise InvalidRequestError("Detected a mapped object not present in the current thread's Identity Map: '%s'. Use objectstore.import_instance() to place deserialized instances or instances from other threads" % repr(obj._instance_key)) +# if hasattr(obj, '_instance_key') and not self.identity_map.has_key(obj._instance_key): +# raise InvalidRequestError("Detected a mapped object not present in the current thread's Identity Map: '%s'. Use objectstore.import_instance() to place deserialized instances or instances from other threads" % repr(obj._instance_key))

     def update(self, obj):
"""called to add an object to this UnitOfWork as though it were loaded from the DB,

feel free to play around with either of these. I am not opposed to adding switches to put these into effect, on a global or per-mapper/ per-session basis; however I dont have the resources to support issues related to side-effects of these modifications, since its essentially a different ORM.


On Mar 26, 2006, at 3:36 PM, Michael Bayer wrote:

theres no caching in SQLAlchemy. theres an identity map which has some of the same effects as a cache. basically, if you have already loaded your object into the current session, thats it. if you load it again, its going to use the same one you have, unless you clear the session, or refresh/expire the object. SA is not going to make a random guess as to what objects you want refreshed and which ones you are expecting to stay linked to the current editing session, which changes you want to keep and which ones youd like to discard.

consider this scenario: you load object A and object B into the current session. objects A and B have state information that is highly interdependent. you then make changes on B which depend highly on the current state of A. Then some functions are called to do some not totally related tasks. As a matter of course, within those function calls some other part of the application makes a select statement which also requests "A", which has now been modified in the database by another process.

returning from the function, A has been magically updated by an unknown actor, and B is now in an invalid state against the new version of A. the application breaks.

the point of the identity map is to prevent the above scenario, and the myriad of variations on it, from occurring. you are assured that every object, once loaded into the session, will not change unexpectedly without your say-so, and because their identity is assured, all changes made to that object identity are reflected consistently throughout the editing session; its state will always be consistent within the session. if you need multiple copies/ states, then you use multiple sessions, or pick and choose who should be refreshed.

if you havent already, I totally overhauled the unit of work documentation yesterady in response to the recent spate of confusion over what an identity map and a unit of work is used for - http://www.sqlalchemy.org/docs/unitofwork.myt . It also details the refresh/expire/expunge methods as well as "per-object sessions" which may also provide a way for you to get fresh copies (i.e. myobj = mapper.using(Session()).get(1) will always be fresh...and unsaveable unless you import it into another session since the original one falls out of scope)

also, I would recommend Fowler's "Patterns of Enterprise Architecture" which is where I learned about all these patterns: http://www.martinfowler.com/books.html#eaa . SQLAlchemy's ORM is a python version of the "unit of work", "data mapper", and "identity map" patterns described in this book. If those arent the patterns you want to use, its going to be more of an uphill battle trying to make SA be something its not....but even then, it is possible, youd just have to write a layer on top of it to provide the patterns youre looking for (or write an ORM on top of the SQL construction facilities).


On Mar 26, 2006, at 1:33 PM, Florian Boesch wrote:

Seemingly SA is fairly liberal with interpreting my wish to get stuff from the
database.

So what's the pattern to deal with "session" "caching"?

I hear there's expunge etc. now, and expire, but that's all when I know what objects I want to have removed/expired/refreshed. Fact is, I don't, I wouldn't ask for an object from the database when I already had that very object...

So is there a way to end a session by force?
Can I disable all caching?
How do I deal with that?






-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to