2011-06-19 67 views
1

我将缩略图图像作为BlobStoreProperties存储在Google App引擎实体中。随着时间的推移,缩略图需要更新,我通过用新的图像数据更新这些实体的内容来完成更新。但是,我发现任何后续检索这些图像仍会返回实体中第一次保存的相同旧副本。这是令人惊讶的不一致的行为。我写了一个简单的独立代码来验证这一点。Google App Engine BlobProperty返回陈旧内容

这里有两个简单的处理程序和一个模型定义。 SaveImageHandler将图像保存到数据存储区,LoadImageHandler检索它。

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() 

我上传的图像这样

curl -F "[email protected]/tmp/img1.png" http://ubuntu.local:8000/_thumbsave/X 

我检索图像

curl -d dummy=0 http://ubuntu.local:8000/_thumbload/X > Downloads/imgout.png 

imgout.pngimg1.png相同

然后我上传其他图片img2.png

curl -F "[email protected]/tmp/img2.png" http://ubuntu.local:8000/_thumbsave/X 

然后以上面的相同方式检索它。我期望现在imgout.pngimg2.png相同。但是,我发现它仍然是旧的img1.png。因此Image查询返回了陈旧的对象。打印图像长度的日志语句也会验证第二次返回的图像不是更新后的图像。

这里怎么回事?

回答

3

在你SaveImageHandler要创建一个新的Image实体每次您发布的图像数据的时间,那么你只是与UID获取的第一图像在LoadImageHandler

将其更改为“寻找或创造”像这样的:

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() 

不是使用uid性质,考虑使用key_names为目的,并采取看看get_or_insert方法

+0

哇。非常尴尬现在忽略这一点。感谢您指出。 – Jayesh

+0

键名肯定是在这里做的正确的事情 - 他们会避免这个问题,并减少开销的开销。 –