gpt4 book ai didi

python - 端点原始数据存储 - 用于 key 的路径 {require} 变量随机中断

转载 作者:太空宇宙 更新时间:2023-11-03 17:29:55 26 4
gpt4 key购买 nike

我正在使用 Endpoints 和 Endpoints Proto Datastore 构建 API,并使用 App Engine Launcher 进行测试。下面的代码是我用来构建两层深度的嵌套实体(祖 parent / parent / child )的代码。

变量_child返回'None'(在第98行设置)看似随机,这破坏了第139行的ndb.Key并且143 并导致 BadArgumentError:不完整的 key 输入必须位于最后


import endpoints
from google.appengine.ext import ndb
from protorpc import remote

from endpoints_proto_datastore.ndb import EndpointsAliasProperty
from endpoints_proto_datastore.ndb import EndpointsModel

import logging


project_api = endpoints.api(name='project', version='v1', description='Project API')


""" Grandparent """


class GrandparentModel(EndpointsModel):
_message_fields_schema = ('grandparent',)

def set_grandparent(self, value):
if not isinstance(value, basestring):
raise TypeError('Grandparent name must be a string.')
self.UpdateFromKey(ndb.Key(GrandparentModel, value))

@EndpointsAliasProperty(setter=set_grandparent, required=True)
def grandparent(self):
if self.key is not None:
return self.key.string_id()


""" Parent """


class ParentModel(EndpointsModel):

_message_fields_schema = ('grandparent', 'parent',)

_grandparent = None
_parent = None

def set_key(self):
if self._grandparent is not None and self._parent is not None:
key = ndb.Key(GrandparentModel, self._grandparent, ParentModel, self._parent)
self.UpdateFromKey(key)

def set_parts(self):
if self.key is not None:
grandparent_pair, parent_pair = self.key.pairs()

self._grandparent = grandparent_pair[1]
self._parent = parent_pair[1]

# Grandparent

def set_grandparent(self, value):
if not isinstance(value, basestring):
raise TypeError('Grandparent name must be a string.')

self._grandparent = value

if ndb.Key(GrandparentModel, value).get() is None:
raise endpoints.NotFoundException('Grandparent %s does not exist.' % value)

self.set_key()
self._endpoints_query_info.ancestor = ndb.Key(GrandparentModel, value)

@EndpointsAliasProperty(setter=set_grandparent, required=True)
def grandparent(self):
if self._grandparent is None:
self.set_parts()
return self._grandparent

# Parent

def set_parent(self, value):
if not isinstance(value, basestring):
raise TypeError('Parent must be a string.')

self._parent = value
self.set_key()

@EndpointsAliasProperty(setter=set_parent, required=True)
def parent(self):
if self._parent is None:
self.set_parts()
return self._parent


""" Child """


class ChildModel(EndpointsModel):

_message_fields_schema = ('grandparent', 'parent', 'child',)

_grandparent = None
_parent = None
_child = None

def set_key(self):
if self._grandparent is not None and self._parent is not None and self._child is not None:
key = ndb.Key(GrandparentModel, self._grandparent, ParentModel, self._parent, ChildModel, self._child)
self.UpdateFromKey(key)

def set_parts(self):
if self.key is not None:
grandparent_pair, parent_pair, child_pair = self.key.pairs()

self._grandparent = grandparent_pair[1]
self._parent = parent_pair[1]
self._child = child_pair[1]

# Grandparent

def set_grandparent(self, value):
if not isinstance(value, basestring):
raise TypeError('Grandparent must be a string.')

self._grandparent = value
self.set_key()

@EndpointsAliasProperty(setter=set_grandparent, required=True)
def grandparent(self):
if self._grandparent is None:
self.set_parts()
return self._grandparent

# Parent

def set_parent(self, value):
if not isinstance(value, basestring):
raise TypeError('Parent name must be a string.')

self._parent = value

logging.warning('Check _grandparent value: %s' % self._grandparent)
logging.warning('Check _parent value: %s' % self._parent)

if ndb.Key(GrandparentModel, self._grandparent, ParentModel, value).get() is None:
raise endpoints.NotFoundException('Key %s does not exist.' % value)

self.set_key()
self._endpoints_query_info.ancestor = ndb.Key(GrandparentModel, self._grandparent, ParentModel, value)

@EndpointsAliasProperty(setter=set_parent, required=True)
def parent(self):
if self._parent is None:
self.set_parts()
return self._parent

# Child

def set_child(self, value):
if not isinstance(value, basestring):
raise TypeError('Child must be a string.')

self._child = value
self.set_key()

@EndpointsAliasProperty(setter=set_child, required=True)
def child(self):
if self._child is None:
self.set_parts()
return self._child


@project_api.api_class(resource_name='grandparent')
class Grandparent(remote.Service):

@GrandparentModel.method(name='insert', path='grandparent')
def grandparent_insert(self, grandparent):
grandparent.put()
return grandparent

@GrandparentModel.query_method(name='list', path='grandparent')
def grandparent_list(self, query):
return query


@project_api.api_class(resource_name='parent', path='grandparent')
class Parent(remote.Service):

@ParentModel.method(name='insert', path='{grandparent}/parent')
def parent_insert(self, parent):
parent.put()
return parent

@ParentModel.query_method(name='list', path='{grandparent}/parent', query_fields=('grandparent',))
def parent_list(self, query):
return query


@project_api.api_class(resource_name='child', path='grandparent')
class Child(remote.Service):

@ChildModel.method(name='insert', path='{grandparent}/parent/{parent}/child')
def child_insert(self, child):
child.put()
return child

@ChildModel.query_method(name='list', path='{grandparent}/parent/{parent}/child',
query_fields=('grandparent', 'parent',))
def child_list(self, query):
return query


application = endpoints.api_server([project_api], restricted=False)

这是中断时的日志:

INFO     2015-08-16 10:26:50,503 module.py:809] default: "POST /_ah/spi/BackendService.getApiConfigs HTTP/1.1" 200 8577INFO     2015-08-16 09:26:52,099 main.py:136] Check _grandparent value: gINFO     2015-08-16 09:26:52,099 main.py:137] Check _parent value: pINFO     2015-08-16 10:26:52,108 module.py:809] default: "POST /_ah/spi/Child.child_list HTTP/1.1" 200 2INFO     2015-08-16 10:26:52,109 module.py:809] default: "GET /_ah/api/project/v1/grandparent/g/parent/p/child HTTP/1.1" 200 2INFO     2015-08-16 10:26:59,165 module.py:809] default: "POST /_ah/spi/BackendService.getApiConfigs HTTP/1.1" 200 8577INFO     2015-08-16 09:26:59,168 main.py:136] Check _grandparent value: NoneINFO     2015-08-16 09:26:59,168 main.py:137] Check _parent value: pERROR    2015-08-16 09:26:59,168 service.py:191] Encountered unexpected error from ProtoRPC method implementation: BadArgumentError (Incomplete Key entry must be last)Traceback (most recent call last):  File "C:\Development\Google\google_appengine\lib\protorpc-1.0\protorpc\wsgi\service.py", line 181, in protorpc_service_app    response = method(instance, request)  File "C:\Development\Google\google_appengine\lib\endpoints-1.0\endpoints\api_config.py", line 1332, in invoke_remote    return remote_method(service_instance, request)  File "C:\Development\Google\google_appengine\lib\protorpc-1.0\protorpc\remote.py", line 414, in invoke_remote_method    response = method(service_instance, request)  File "C:\Development\_Projects\API\project\endpoints_proto_datastore\ndb\model.py", line 1574, in QueryFromRequestMethod    request_entity = cls.FromMessage(request)  File "C:\Development\_Projects\API\project\endpoints_proto_datastore\ndb\model.py", line 1245, in FromMessage    setattr(entity, name, value)  File "C:\Development\_Projects\API\project\main.py", line 139, in set_parent    if ndb.Key(GrandparentModel, self._grandparent, ParentModel, value).get() is None:  File "C:\Development\Google\google_appengine\google\appengine\ext\ndb\key.py", line 220, in __new__    self.__namespace) = self._parse_from_args(**kwargs)  File "C:\Development\Google\google_appengine\google\appengine\ext\ndb\key.py", line 245, in _parse_from_args    'Incomplete Key entry must be last')BadArgumentError: Incomplete Key entry must be lastINFO     2015-08-16 10:26:59,174 module.py:809] default: "POST /_ah/spi/Child.child_list HTTP/1.1" 500 512INFO     2015-08-16 10:26:59,174 module.py:809] default: "GET /_ah/api/project/v1/grandparent/g/parent/p/child HTTP/1.1" 503 196

到目前为止,我自己还无法解决这个问题,因此我们将不胜感激。

谢谢!

最佳答案

更新:您假设在sort_keys中,当从祖 parent 的路径解析parent时,已经解析完毕:

    if self._grandparent is None:
raise Exception('set_parent: self._grandparent is None')

为避免此问题,请不要依赖于 grandparentparent 的设置顺序。

说明:每次运行该过程时,字段的顺序可能会有所不同。当 endpoints 库检测到您的路径中有字段时,CombinedContainer 消息类为 created on the fly :此类的字段以任意顺序设置。 (用于创建 CombinedContainer 的字段来自输出 Message.all_fields()。但是 Message 使用 dictionary 来存储字段名称,然后 all_fields() uses dict.values() 作为值。在 Python 中,字典顺序是不确定的,因此它们可能以任何可能的顺序返回。)

然后在endpoints-proto-datastore中,CombinedContainer中的字段为sorted按字段编号。此排序顺序在用户定义的类中很重要,但当用户不控制 CombinedContainer 的创建时,该排序顺序将被“忽略”。

请注意,在 keys with ancestors exampleIdSet 方法调用 SetKey,但 SetKey 确保父级和 ID 均已设置

if self._parent is not None and self._id is not None:
...
<小时/>

简短回答:使用

'grandparent/{grandparent}/parent/{parent}/child'

作为您的路径模板。

<小时/>

长答案:发送的请求与 PATH 模板不匹配。

您的 URI 模板是

'{grandparent}/parent/{parent}/child'

但你的道路是

/_ah/api/project/v1/grandparent/g/parent/p/child

对应的相对路径

grandparent/g/parent/p/child

根据匹配的工作方式(我不确定),您要么根本没有匹配到 {grandparent} ,而是与 grandparent/g 匹配.

从您的堆栈跟踪来看,您根本没有匹配项。

关于python - 端点原始数据存储 - 用于 key 的路径 {require} 变量随机中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32033607/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com