I thought I'd share this, since I'm sure there are others that have
fallen into the same trap using this very common pattern (in this
sample, Pix derives from db.Model; get_pics is called on every page
load):

        def get_pics(self):
                pics = memcache.get("pics")
                if pics is None:
                        pics = Pix.gql("LIMIT 100")
                        memcache.add("pics", pics, 300)         # Good for 5 
minutes
                return pics

See the bug?  Here, memcache is actually HURTING performance since the
overhead of memcache is there but it saves nothing at all.  The query
is still executed on every page load when the calling code iterates
through the result.

http://code.google.com/appengine/docs/python/datastore/queryclass.html#Introduction
mentions this by saying "creating a new iterator from the Query object
will re-execute the query", but it doesn't highlight this pitfall.
The issue here is that entities are not fetched on the Pix.gql line.
Instead, that simply returns a Query object.  The results are actually
fetched when the calling code begins to iterate (in Python-speak, the
__iter__() method on the Query is what actually fetches entities).

To fix this, you'd change the gql line to :
                        pics = list(Pix.gql("LIMIT 100"))
Putting a list() around the Pix.gql forces the query to happen at that
moment.  Then the list of entities is stored in memcache, not the
Query object itself.

I'm not sure if this applies to the Java API too, but it's worth a
heads-up.

Comments welcome...

--

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


Reply via email to