【问题标题】:PicklingError: Can't pickle <class ...>: it's not the same object as ... in GAEPicklingError: Can't pickle <class ...>: it's not the same object as ... in GAE
【发布时间】:2012-01-23 02:38:56
【问题描述】:

我的 GAE Python 应用程序中的这行代码出现 PicklingError:

deferred.defer(email_voters_begin, ekey, voter_list)

三个参数是:

  • email_voters_begin -- Python 函数,例如,函数 email_voters_begin 位于 0x1035d4488
  • 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

请注意,在deferred.defer() 中传递的Voter 实体没有BlobReference 属性,但Voter 实体确实具有ReferenceProperty 到另一个具有BlobReference 属性的实体。我认为任何 BlobInfo 对象都不会成为泡菜的一部分,但错误表明其中包含一个。

当我使用开发服务器从浏览器窗口运行相同的代码时,不会发生此错误。

我不知道如何调试它,任何想法都将不胜感激。

【问题讨论】:

    标签: python google-app-engine pickle


    【解决方案1】:

    这很可能是因为您在至少一个 Voter 对象上检索到了ReferenceProperty。一旦取消引用 ReferenceProperty,模型实例就会缓存它。 Pickling 也会腌制任何缓存的对象,因此它会尝试序列化 Voter 实例、引用的实例及其 BlobInfo

    一般来说,正如 Skirmantas 所指出的,将模型实例传递给 deferred 通常是个坏主意。在可能的情况下,发送密钥,如果没有,将实例序列化到协议缓冲区并发送它们。

    【讨论】:

      【解决方案2】:

      您永远不应该将模型实例传递给 deferred。改用键:

      deferred.defer(email_voters_begin, ekey, [v.key() for v in voter_list])
      

      在您的 email_voters_begin 中:

      def email_voters_begin(ekey, voters_keys):
          voter_list = models.Voter.get(voters_keys)
      

      【讨论】:

        猜你喜欢
        • 2010-11-27
        • 2021-08-21
        • 2020-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多