PicklingError:无法 pickle:它与 GAE 中的 ... 不是同一对象
我从我的 GAE Python 应用程序中的这行代码中收到 PicklingError:
deferred.defer(email_voters_begin, ekey, voter_list)
三个参数是:
- email_voters_begin -- 一个 Python 函数,例如位于 0x1035d4488 的函数 email_voters_begin
- ekey -- 我定义的实体的密钥,例如,打印为 agdvcGF2b3Rlcg4LEghFbGVjdGlvbhgCDA
- voter_list -- 我定义的对象列表,例如,[models.Voter object at 0x103d3d310, ... ]
当此行作为我的测试的一部分执行时(使用 webtest 和 nosegae),我收到以下错误:
Traceback (most recent call last):
[...]
File "/Users/joneill/OpenSTV/OpenSTV/trunk/OpaVote-HR/tasks.py", line 29, in init_voters_and_send_email
deferred.defer(email_voters_begin, ekey, voter_list)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/deferred/deferred.py", line 249, in defer
pickled = serialize(obj, *args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/deferred/deferred.py", line 221, in serialize
return pickle.dumps(curried, protocol=pickle.HIGHEST_PROTOCOL)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
[...]
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 396, in save_reduce
save(cls)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 753, in save_global
(obj, module, name))
PicklingError: Can't pickle <class 'google.appengine.ext.blobstore.blobstore.BlobInfo'>: it's not the same object as google.appengine.ext.blobstore.blobstore.BlobInfo
请注意,Voter
实体已通过deferred.defer()
中没有 BlobReference
属性,但 Voter
实体确实有ReferenceProperty
到另一个具有 BlobReference
属性的实体。我不认为任何 BlobInfo 对象都会成为 pickle 的一部分,但错误表明其中包含一个。
当我使用开发服务器从浏览器窗口运行相同的代码时,不会发生此错误。
我对如何调试这个感到困惑,任何想法将不胜感激。
I'm getting a PicklingError from this line of code in my GAE Python app:
deferred.defer(email_voters_begin, ekey, voter_list)
The three arguments are:
- email_voters_begin -- A Python function, eg., function email_voters_begin at 0x1035d4488
- ekey -- A key to an entity I defined, eg., prints as agdvcGF2b3Rlcg4LEghFbGVjdGlvbhgCDA
- voter_list -- A list of objects I defined, eg., [models.Voter object at 0x103d3d310, ... ]
When this line executes as part of my tests (with webtest and nosegae), I get the following error:
Traceback (most recent call last):
[...]
File "/Users/joneill/OpenSTV/OpenSTV/trunk/OpaVote-HR/tasks.py", line 29, in init_voters_and_send_email
deferred.defer(email_voters_begin, ekey, voter_list)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/deferred/deferred.py", line 249, in defer
pickled = serialize(obj, *args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/deferred/deferred.py", line 221, in serialize
return pickle.dumps(curried, protocol=pickle.HIGHEST_PROTOCOL)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
[...]
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 396, in save_reduce
save(cls)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 753, in save_global
(obj, module, name))
PicklingError: Can't pickle <class 'google.appengine.ext.blobstore.blobstore.BlobInfo'>: it's not the same object as google.appengine.ext.blobstore.blobstore.BlobInfo
Note that the Voter
entities passed in deferred.defer()
do not have a BlobReference
property, but the Voter
entities do have a ReferenceProperty
to another entity that does have a BlobReference
property. I wouldn't think that any BlobInfo objects would be part of the pickle but the error suggests one is being included.
This error does not occur when I run the same code from a browser window using the dev server.
I'm stumped as how to debug this and any ideas would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
发生这种情况的原因可能是您已检索至少一个 Voter 对象的
ReferenceProperty
。一旦取消引用ReferenceProperty
,模型实例就会缓存它。 Pickling 也会腌制任何缓存的对象,因此它会尝试序列化Voter
实例、引用的实例及其BlobInfo
。一般来说,正如 Skirmantas 指出的那样,将模型实例传递给 deferred 通常不是一个好主意。如果可能,请发送密钥,如果没有,请将实例序列化到协议缓冲区并发送它们。
This is likely occurring because you've retrieved the
ReferenceProperty
on at least one of the Voter objects. Once you dereference aReferenceProperty
, the model instance caches it. Pickling pickles any cached objects too, so it attempts to serialize theVoter
instance, the referenced instance, and itsBlobInfo
.In general, as Skirmantas points out, it's usually a bad idea to pass model instances to deferred. Where possible, send keys, and if not, serialize the instances to Protocol Buffers and send those instead.
您永远不应该将模型实例传递给延迟模型。请改用密钥:
在您的 email_voters_begin 中:
You should never pass instances of models to a deferred. Use keys instead:
In your email_voters_begin: