ProtocolBufferDecodeError,"truncated" 使用 ndb.Key(urlsafe=

ProtocolBufferDecodeError, "truncated" when inserting key using ndb.Key(urlsafe=

我在使用 ndb.Key() 方法并使用 urlsafe 参数时收到错误消息。
您会看到很多我用来临时查找错误来源的日志记录语句。我已将范围缩小到这一行:

resource_section = ndb.Key(urlsafe=request.resource_section_key

我使用相同的语法在这一行的前一行插入资源密钥,并且成功了。我已验证该实体存在于数据存储区中。我已经为此工作了几天,我希望你们中的一个能看到我遗漏的东西。

代码如下:

    if request.knowledge_key:
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.knowledge_key = " + request.knowledge_key) 
        # If no key exists, then we can assume it needs to be inserted
        # into the datastore.  Overwrite any exiting values with what
        # is passed into the method
        kno=ndb.Key(urlsafe=request.knowledge_key).get()
        kno.knowledge = request.knowledge
        kno.resource = ndb.Key(urlsafe=request.resource_key)
        kno.resource_section = ndb.Key(urlsafe=request.resource_section_key)
        kno.types = request.types
        kno.page = request.page
        kno.keywords = request.keywords
        kno.put()

    else:
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.knowledge = " + request.knowledge) 
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.resource_key = " + request.resource_key) 
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.resource_section_key = " + request.resource_section_key)
        types_string = ""
        for item in request.types:
            types_string += item.strip()
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.types = " + types_string)

        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.page = " + str(request.page)) 
        keywords_string = ""
        for item in request.keywords:
            keywords_string += item.strip()
        logging.info("Logging: class KnowledgeMessageApi.insert_knowledge() - request.keywords = " + keywords_string) 
        #get resource key and name
        Knowledge(parent=PARENT_KEY,
                  knowledge=request.knowledge, 
                  resource = ndb.Key(urlsafe=request.resource_key),
                  resource_section = ndb.Key(urlsafe=request.resource_section_key),
                  types = types_string.split(","),
                  page = request.page,
                  keywords = keywords_string.split(",")
                  ).put()

    return request

我的堆栈跟踪如下:

    INFO     2016-07-18 18:37:16,440 module.py:788] default: "POST /_ah/spi/BackendService.getApiConfigs HTTP/1.1" 200 3958
INFO     2016-07-18 18:37:16,649 apiuser.py:20] Logging: Class ApiUser.__init__ - beginning.
INFO     2016-07-18 18:37:16,649 apiuser.py:22] Logging: Class ApiUser.__init__ - endpoints_user = endpoints.get_current_user()
INFO     2016-07-18 18:37:16,649 apiuser.py:24] Logging: Class ApiUser.__init__ - an endpoints_user exists.
INFO     2016-07-18 18:37:16,649 apiuser.py:44] Logging: Class ApiUser.__init__ - locating from endpoints email.
INFO     2016-07-18 18:37:16,661 apiuser.py:53] Logging: Class ApiUser.__init__ - attempting to populate the object.
INFO     2016-07-18 18:37:16,661 apiuser.py:57] Logging: Class ApiUser.__init__ - self.email = knouser_object.contact_email.
INFO     2016-07-18 18:37:16,661 apiuser.py:59] Logging: Class ApiUser.__init__ - self.email = knouser_object.contact_email.
INFO     2016-07-18 18:37:16,661 apiuser.py:61] Logging: Class ApiUser.__init__ - self.user_id = knouser_object.login_user_id.
INFO     2016-07-18 18:37:16,661 apiuser.py:63] Logging: Class ApiUser.__init__ - self.knouser_key_urlsafe = knouser_object.key.urlsafe().
INFO     2016-07-18 18:37:16,661 apiuser.py:65] Logging: Class ApiUser.__init__ - if knouser_object.organization:.
INFO     2016-07-18 18:37:16,661 apiuser.py:67] Logging: Class ApiUser.__init__ - self.org_key_urlsafe = knouser_object.organization.urlsafe().
INFO     2016-07-18 18:37:16,661 api_knowledge.py:56] Logging: class KnowledgeMessageApi.insert_knowledge() - authenticated_user.email = stewart.jamie@swchristian.com
INFO     2016-07-18 18:37:16,662 api_knowledge.py:58] Logging: class KnowledgeMessageApi.insert_knowledge() - authenticated_user.get_org_key()
INFO     2016-07-18 18:37:16,662 api_knowledge.py:75] Logging: class KnowledgeMessageApi.insert_knowledge() - request.knowledge = This is a test insert of knowledge.
INFO     2016-07-18 18:37:16,662 api_knowledge.py:76] Logging: class KnowledgeMessageApi.insert_knowledge() - request.resource_key = ahdkZXZ-amFtZXNzdGUtc2Nob29sLWFwcHJLCxIGRW50aXR5IhFvcmdhbml6YXRpb25fcm9vdAwLEgxPcmdhbml6YXRpb24YgICAgIDQpwoMCxIIUmVzb3VyY2UYgICAgIDElQoM
INFO     2016-07-18 18:37:16,662 api_knowledge.py:77] Logging: class KnowledgeMessageApi.insert_knowledge() - request.resource_section_key = ahdkZXZ-amFtZXNzdGUtc2Nob29sLWFwcHJSCxIGRW50aXR5IhFvcmdhbml6YXRpb25fcm9vdAwLEgxPcmdhbml6YXRpb24YgICAgIDQpwoMCxIPUmVzb3VyY2VTZWN0aW9uGICAgICA5OU
INFO     2016-07-18 18:37:16,662 api_knowledge.py:81] Logging: class KnowledgeMessageApi.insert_knowledge() - request.types = literature
INFO     2016-07-18 18:37:16,662 api_knowledge.py:83] Logging: class KnowledgeMessageApi.insert_knowledge() - request.page = 2
INFO     2016-07-18 18:37:16,662 api_knowledge.py:87] Logging: class KnowledgeMessageApi.insert_knowledge() - request.keywords = 
ERROR    2016-07-18 18:37:16,662 service.py:191] Encountered unexpected error from ProtoRPC method implementation: ProtocolBufferDecodeError (truncated)
Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/wsgi/service.py", line 181, in protorpc_service_app
    response = method(instance, request)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/endpoints-1.0/endpoints/api_config.py", line 1331, in invoke_remote
    return remote_method(service_instance, request)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/remote.py", line 414, in invoke_remote_method
    response = method(service_instance, request)
  File "/Users/jamesste/Documents/code/jamesste-school-app/api_knowledge.py", line 92, in insert_knowledge
    resource_section = ndb.Key(urlsafe=request.resource_section_key),
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/key.py", line 230, in __new__
    self.__namespace) = self._parse_from_ref(cls, **kwargs)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/key.py", line 318, in _parse_from_ref
    reference = _ReferenceFromSerialized(serialized)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/key.py", line 821, in _ReferenceFromSerialized
    return entity_pb.Reference(serialized)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/entity_pb.py", line 1782, in __init__
    if contents is not None: self.MergeFromString(contents)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 152, in MergeFromString
    self.MergePartialFromString(s)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 168, in MergePartialFromString
    self.TryMerge(d)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/entity_pb.py", line 1927, in TryMerge
    d.skip(length)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 650, in skip
    if self.idx + n > self.limit: raise ProtocolBufferDecodeError, "truncated"
ProtocolBufferDecodeError: truncated
INFO     2016-07-18 18:37:16,671 module.py:788] default: "POST /_ah/spi/KnowledgeMessageApi.insert_knowledge HTTP/1.1" 500 512
INFO     2016-07-18 18:37:16,672 module.py:788] default: "POST /_ah/api/knowledge/v1/knowledge?alt=json HTTP/1.1" 503 196

型号:

class Knowledge(ndb.Model):
    resource=ndb.KeyProperty(kind=Resource)
    resource_section=ndb.KeyProperty(kind=ResourceSection)
    types=ndb.StringProperty(repeated=True) #system-level categories
    knowledge=ndb.StringProperty()
    page=ndb.IntegerProperty()
    keywords=ndb.StringProperty(repeated=True) #unregulated grouping types

resource_section 实体存在的证明: resource_section entity screenshot

经过多次挠头和小憩后,我做了我从未做过的事情......我手动干预以获得积极的结果,结果失去了产生错误的状态。因此,我将此作为答案发布,但它不是确定的答案。因此,我注释掉了那行代码并完成了没有 ResourceSection 键的插入。由于当 属性 中有 None 值时应用程序中断,我通过 Google Cloud Platform 上的数据存储实用程序手动插入密钥。从这一点开始,代码正常执行,包括编辑和插入。虽然我不知道为什么会收到错误,但它可能与这是第一个 Knowledge 实体插入有关。无论如何,我不再有这个问题了。