Reputation: 53345
I store thumbnail images in Google App engine entities as BlobStoreProperties. Over time thumbnails need to be updated, which I do by updating the content of these entities with fresh image data. However I found out that any subsequent retrieval of these images still returns the same old copy that was saved first time in the entity. It's surprisingly inconsistent behavior. I wrote a simple standalone code to verify this.
Here are two simple handlers and a model definition. SaveImageHandler saves the image to datastore and LoadImageHandler retrieves it.
from google.appengine.ext import db
import logging
class Image(db.Expando):
data = db.BlobProperty(required=True)
uid = db.StringProperty(required=True)
class SaveImageHandler(webapp.RequestHandler):
def post(self, uid):
imgdata = self.request.POST.get('imgdata').file.read()
logging.error('Saving %d bytes'%(len(imgdata)))
image = model.Image(data=imgdata, uid=uid)
image.put()
class LoadImageHandler(webapp.RequestHandler):
def post(self, uid):
image = model.Image.gql('WHERE uid = :1', uid).get()
self.response.headers['Content-type'] = 'image/png'
logging.error('Loading %d bytes'%(len(image.data)))
self.response.out.write(image.data)
def application():
return webapp.WSGIApplication([
('/_thumbsave/(.*)', SaveImageHandler),
('/_thumbload/(.*)', LoadImageHandler),
],debug=False)
def main():
util.run_wsgi_app(application())
if __name__ == '__main__':
main()
I upload an image like this
curl -F "imgdata=@/tmp/img1.png" http://ubuntu.local:8000/_thumbsave/X
I retrieve the image
curl -d dummy=0 http://ubuntu.local:8000/_thumbload/X > Downloads/imgout.png
imgout.png
and img1.png
are same
Then I upload another image img2.png
curl -F "imgdata=@/tmp/img2.png" http://ubuntu.local:8000/_thumbsave/X
Then retrieve it in same way above. I expect now imgout.png
to be same as img2.png
. But instead I find that it's still the same old img1.png. Thus the Image query, returned stale object. The log statements that print the length of image, also verify that the image returned second time is not the updated one.
What's going wrong here?
Upvotes: 1
Views: 719
Reputation: 14185
In your SaveImageHandler
you are creating a new Image
entity each time you POST your image data, then you are just fetching the first image with that uid in your LoadImageHandler
Change it to 'find or create' the image like:
class SaveImageHandler(webapp.RequestHandler):
def post(self, uid):
image = Image.all().filter("uid =", uid).get()
if not image:
image = model.Image(uid=uid)
image.data = self.request.POST.get('imgdata').file.read()
image.put()
Rather than using a uid
property, think about using key_names
for that purpose, and take a look at the get_or_insert method
Upvotes: 3