Short version:
I want to execute code during creation of a Model subclass but I need
to know whether or not the object is saved in the datastore and/or
execute datastore queries. Since Model.is_saved() never returns True
inside __init__(), overriding this method doesn't work. I also tried
intercepting construction with a metaclass, and numerous other
approaches, but nothing I've tried works. From examining the source
code it appears that the Model objects aren't fully constructed until
after get() returns, but there doesn't seem to be a convenient,
documented location to put my intercept code.

My specific situation is that I want to replace a ReferenceProperty
with a value I have stored in a cache to avoid a trip to the
datastore.

Here's an example:
class A(db.Model):
  str = db.StringProperty()

class B(db.Model):
  a = db.ReferenceProperty(A)

I want the following code to succeed (assuming B is stored in
datastore):
a = from_cache(a_key)
b = B.get(key)
assert a == b.a

I can populate B.a with the proper value using something like the
following in B:
def Load(self):
  a_key = B.a.get_value_for_datastore(self)
  self.a = from_cache(a_key)

But I can't figure out where to put the call to Load().

Long version:
The reason I'm trying to do this is for performance. I have some very
long-lived objects that use ReferenceProperty to manage relationships
between them, plus a large number of frequently-created objects that
use ReferenceProperty to refer to the long-lived objects. After many
DeadlineExceededErrors I started using memcache to store the long-
lived objects. That helped but not enough. Profiling showed that most
of my time was now being spent in memcache, apparently because
memcache goes to the network on every get() call. So I introduced an
in-memory cache in front of memcache and now first search in-memory,
then in memcache, then go to the datastore.

That helped a lot and I'm now avoiding the DeadlineExceededErrors but
many of my pages still take many seconds to load. Further profiling
pointed out that the ReferenceProperty attributes (primarily in my
frequently-created objects that refer to my long-lived objects) are
hitting the datastore and causing most of my performance problems.
That's the problem I'm trying to solve -- I want to be able to load
all those objects and have them use the cached long-lived objects
instead of going to the datastore to get them.

I thought this would be a common problem but I haven't been able to
find anyone else addressing this. Either I'm not looking in the right
place, people haven't addressed this yet, those who have are not
sharing, or my data model is screwed up and doesn't work with the
AppEngine datastore very well!

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to