我第一次尝试在App Engine上使用memcache,结果遇到了一个"PicklingError“。
我第一次尝试memcache的地方是在网站的主页上,在那里我从数据存储中抓取内容:
def get(self):
content = memcache.get('home:content')
if content is None:
all_content = Content.all()
all_content.order("-views")
all_content.filter('published =', True)
content = all_content.run(batch_size=5, limit=5)
memcache.add(key='home:content', value=content, time=120)(请注意,即使我没有尝试将内容查询对象放入memcache中,也可以很好地工作。下面是它在最后一行命中的错误(memcache.add...):
PicklingError: Pickling of datastore_query.Batcher is unsupported.以下是内容的模型:
class Content(db.Model):
category = db.StringProperty(required = True)
content_type = db.StringProperty(required = True)
published = db.BooleanProperty(default = False)
title = db.StringProperty(required = True)
abstract = db.TextProperty(required = True)
summary = db.TextProperty(required = True)
URL = db.LinkProperty(required = True)
youtube_id = db.StringProperty(required = False)
thumbnail = db.LinkProperty(required = True)
post_author = db.StringProperty(required = True)
author_url = db.LinkProperty(required = False)
date_post = db.DateTimeProperty(required = True, auto_now_add = True)
date_source = db.DateTimeProperty(required = False)
# todo: split out to use decent shardedcounter approach
views = db.IntegerProperty(default = 0)
up_votes = db.IntegerProperty(default = 0)
down_votes = db.IntegerProperty(default = 0)
def votes(self):
return self.up_votes - self.down_votes我正在努力弄清楚什么是PicklingError,以及它与试图将Query对象存储到memcache中有何关系。我的问题是:我做错了什么?这是因为我正在尝试缓存迭代器吗?缓存Query对象并需要在每次页面加载时调用.run()有什么价值吗?
发布于 2012-11-24 02:50:08
看看memcache的source。
简而言之,这是因为您的值必须以一种简单的方式序列化,所以默认情况下使用pickle (实际上是cPickle)来序列化您传入的对象。
当调用add时,将调用_set_with_policy,后者随后将调用_set_multi_async_with_policy。在_set_multi_async_with_policy中,键-值对作为mapping传入,并且是serialized in a loop
for key, value in mapping.iteritems():
server_key = _key_string(key, key_prefix, user_key)
stored_value, flags = _validate_encode_value(value, self._do_pickle)在帮助器方法_validate_encode_value中,如果传入的对象是不可识别的对象,如int、bool、str,则方法attempts to pickle该对象:
else:
stored_value = do_pickle(value)
flags |= TYPE_PICKLED更新:当您调用run时,您将获得一个iterator object,其中包含查询中包含的某些对象。如果你只想要过滤结果,你可以把这个迭代器通过
content = list(all_content.run(batch_size=5, limit=5))如果你想保留其他的部分,你需要一些定制的pickler。在Batcher中作为you can see
def __getstate__(self):
raise pickle.PicklingError(
'Pickling of datastore_query.Batch is unsupported.')datastore_query中定义的大多数类--也就是定义大多数查询行为的类--强烈反对在调用__getstate__时抛出PicklingError。如果您从来没有使用过它,那么__getstate__和__setstate__是一些自定义方法,它们可以帮助您对对象进行pickle和unpickle操作。
https://stackoverflow.com/questions/13530018
复制相似问题