On 3/26/06, Michael Bayer <[EMAIL PROTECTED]> wrote:
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
--
Jonathan Ellis
http://spyced.blogspot.com