我正在使用由Danny Hermes为Google App Engine创建的Endpoints-proto-datastore。
我的模型看起来像这样:
class Datum(EndpointsModel):
year = ndb.IntegerProperty(required=True)
value = ndb.FloatProperty(required=True)
class Variable(EndpointsModel):
name = ndb.StringProperty(required=True)
data = ndb.StructuredProperty(Datum, repeated=True)
class Indicator(EndpointsModel):
name = ndb.StringProperty(required=True)
variables = ndb.KeyProperty(kind=Variable, repeated=True)
formula = ndb.StringProperty(required=True)
我的API是这样的:
@endpoints.api(name="SomeAPI", version="v1", description="someDescription")
class SomeAPI(remote.Service):
@Indicator.query_method(query_fields=("limit", "pageToken"),
name="indicator.list",
path="indicators")
def list_indicators(self, query):
return query
问题在于,当我提出请求时,我得到了
{
"items": [
{
"name": "IndicatorName",
"variables": [
"agtkZXZ-bW9uaXRvcnITCxIIVmFyaWFibGUiBU1BVFJQDA",
"agtkZXZ-bW9uaXRvcnISCxIIVmFyaWFibGUiBFBST1AM"
],
"formula": "someFormula"
}
]
}
但是获取变量键对我来说并不是真的有用,因为这会迫使客户端对指标实体上的变量做出另一个请求。我想获得变量内容,如下所示:
{
"items": [
{
"name": "IndicatorName",
"variables": [
{
"name": "some Variable",
"data": [
{
"value": 230,
"year": 2000,
},
{
"value": 250,
"year": 2005,
}
]
},
{
"name": "some other Variable",
"data": [
{
"value": 230,
"year": 2000,
},
{
"value": 250,
"year": 2005,
},
{
"value": 260,
"year": 2010,
}
]
}
],
"formula": "someFormula"
}
]
}
答案 0 :(得分:2)
那你不想要KeyProperty
。如果您想引用其他属性,请使用ndb.StructuredProperty
:
class Indicator(EndpointsModel):
name = ndb.StringProperty(required=True)
variables = ndb.StructuredProperty(Variable, repeated=True)
在像您这样的高级案例中,引用的对象可能会更改,但键不会更改,您可以使用EndpointsAliasProperty
。有关某些参考点,请参阅docs以获取一些示例或某些StackOverflow问题Using endpoints-proto-datastore, how do you pass attributes to a method that are not contained in the EndpointsModel或Cloud Endpoints - Retrieving a single entity from datastore (by a property other than the helper methods provided by EndpointsModel)。
更新:在添加了有关这些类的更多信息后,我发现了以下特殊需求:
对于这种特定情况,您希望将variables
存储为variable_keys
之类的其他名称,然后使用variables
来检索键的值:
from endpoints_proto_datastore.ndb import EndpointsAliasProperty
class Indicator(EndpointsModel):
name = ndb.StringProperty(required=True)
variable_keys = ndb.KeyProperty(kind=Variable, repeated=True)
formula = ndb.StringProperty(required=True)
然后作为Indicator
上的实例方法定义你的getter(对于variables
)没有关联的setter:
@EndpointsAliasProperty(repeated=True, property_type=Variable.ProtoModel())
def variables(self):
return ndb.get_multi(self.variable_keys)
我还建议在_message_fields_schema
类上设置Indicator
,这样只有在你需要时调用此getter,因为get_multi
是一个昂贵的RPC,如果你不使用它。然后,当您在查询中需要它时,可以将其包含在collection_fields
:
@Indicator.query_method(query_fields=("limit", "pageToken"),
collection_fields=("variables", ...),
name="indicator.list",
path="indicators")
def list_indicators(self, query):
return query
PS:查看PEP8 - Whitespace in Expressions and Statements; “当用于表示关键字参数或默认参数值时,请勿在=符号周围使用空格。”