[ZODB-Dev] Is any function called when an object is loaded from the database?
Claudiu Saftoiu
csaftoiu at gmail.com
Tue Jun 19 17:54:21 UTC 2012
Hello all,
It is often the case that I have a Persistent object that evolves over
time. E.g., it might start off as this:
class Foo(Persistent):
def __init__(self, a):
self.a = a
def calc_it(self, b):
return expensive_function(a, b)
I'll then have a few hundred Foos in my database. Then I'll want to modify
the object, for example to cache the previous calculation.
That is, I want this to be the case, now:
class Foo(Persistent):
def __init__(self, a):
self.a = a
self.b_cache = PersistentDict()
def calc_it(self, b):
if b in self.b_cache: return self.b_cache[b]
res = expensive_function(a, b)
self.b_cache[b] = res
return res
However, this won't work with existing Foo objects, as they won't have the
`b_cache` attribute. Thus I have two options. One is
to make the modifications backwards-compatible, e.g.:
class Foo(Persistent):
def __init__(self, a):
self.a = a
self.b_cache = PersistentDict()
def calc_it(self, b):
if not hasattr(self, 'b_cache'): self.b_cache = PersistentDict()
if b in self.b_cache: return self.b_cache[b]
res = expensive_function(a, b)
self.b_cache[b] = res
return res
The other is to go through the database and add 'b_cache' to all the
existing objects. Neither of these is really appealing.
The former is OK, but if I have multiple functions that want to use the new
functionality I'll have to have the code all
over, and it won't be obviously separated. The latter is rather annoying as
I have to figure out wherever I have Foos and
write throwaway code to change them all.
Ideally I could do something like this:
class Foo(Persistent):
def __init__(self, a):
self.a = a
self.b_cache = PersistentDict()
def __just_loaded__(self):
if not hasattr(self, 'b_cache'): self.b_cache = PersistentDict()
def calc_it(self, b):
if b in self.b_cache: return self.b_cache[b]
res = expensive_function(a, b)
self.b_cache[b] = res
return res
That is, a function called whenever the object is loaded, that does all the
necessary backwards-compatibility
work right there. It separates the backwards-compat code cleanly, and also
only updates the objects
as-needed... though still a minor performance hit as it does the check each
time the object is loaded.
Is there a way to do that last option? What's the best practice for this
sort of thing, in general?
Thanks,
- Claudiu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.zope.org/pipermail/zodb-dev/attachments/20120619/2ccbbeb0/attachment.html>
More information about the ZODB-Dev
mailing list