I am using Endpoints-proto-datastore created by Danny Hermes for Google App Engine.
My model looks something like this:
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)
And my API is something like this:
@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
The problem is that when i make the request, i get
{
"items": [
{
"name": "IndicatorName",
"variables": [
"agtkZXZ-bW9uaXRvcnITCxIIVmFyaWFibGUiBU1BVFJQDA",
"agtkZXZ-bW9uaXRvcnISCxIIVmFyaWFibGUiBFBST1AM"
],
"formula": "someFormula"
}
]
}
But getting the variable keys is not really useful for me, because that would force the client to make another request for the variables on the indicator entity. I would like to get the variable content, like this:
{
"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"
}
]
}
You don't want a
KeyProperty
then. If you want to reference the other property usendb.StructuredProperty
:In advanced cases like yours, where the referenced object may change, but the keys will not, you can use an
EndpointsAliasProperty
. For some point of reference, see the docs for some examples or some StackOverflow questions Using endpoints-proto-datastore, how do you pass attributes to a method that are not contained in the EndpointsModel or Cloud Endpoints - Retrieving a single entity from datastore (by a property other than the helper methods provided by EndpointsModel).UPDATE: After more information about the classes was added, indicating a special need, I added the following:
For this specific case, you'd want to store the
variables
as some other name likevariable_keys
and then usevariables
to retrieve the values of the keys:and then as an instance method on
Indicator
define your getter (forvariables
) with no associated setter:I would also advise setting
_message_fields_schema
on theIndicator
class so this getter is only called when you want it, since theget_multi
is an expensive RPC if you don't use it. Then when you want it in your query, you can include it in thecollection_fields
:PS: Check out PEP8 - Whitespace in Expressions and Statements; "Don't use spaces around the = sign when used to indicate a keyword argument or a default parameter value."