How to create self-referencing EndpointsModel

134 views Asked by At

I'm trying to create following self-referencing EndpointsModel (the trick with _fix_up_properties() is taken from here: https://groups.google.com/forum/#!topic/appengine-ndb-discuss/1FmgEVK7JNM):

class EventFieldSchema(EndpointsModel):
  name = ndb.StringProperty(required=True)
  type = msgprop.EnumProperty(EventType, required=True)

EventFieldSchema.nested_fields = ndb.LocalStructuredProperty(EventFieldSchema,repeated=True)
EventFieldSchema._fix_up_properties()

This works for datastore model, but unfortunately, the nested_fields field won't be included into ProtoRPC message. I've tried to manually specify message fields schema, by adding at the end following line:

EventFieldSchema._message_fields_schema = ('name', 'type', 'nested_fields')

but then app-engine fails, going into a loop, trying turn EventFieldSchema into ProtoRPC field:

Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
  handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
  handler, path, err = LoadObject(self._handler)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 85, in LoadObject
  obj = __import__(path[0])
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/main.py", line 3, in <module>
  from er.api.event import EventRegistryApi
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/er/api/event.py", line 17, in <module>
  class EventRegistryApi(remote.Service):
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/er/api/event.py", line 23, in EventRegistryApi
  name='%s.insert' % RESOURCE_NAME)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0/protorpc/util.py", line 170, in positional_wrapper
  return wrapped(*args, **kwargs)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1359, in method
  kwargs[REQUEST_MESSAGE] = cls.ProtoModel(fields=request_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel
  allow_message_fields=allow_message_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 969, in _MessageFields
  proto_attr = to_proto(prop, field_index)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/utils.py", line 137, in StructuredPropertyToProto
  property_proto = property_proto_method()
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel
  allow_message_fields=allow_message_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 969, in _MessageFields
  proto_attr = to_proto(prop, field_index)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/utils.py", line 137, in StructuredPropertyToProto
  property_proto = property_proto_method()
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel

Is this a bug in EndpointsModel? What is the "proper" way of defining self-referencing EndpointsModels?

1

There are 1 answers

0
Brendan O'Neil On

Having the same issue with self-referencing an EndpointsModel:

class UnitsProtoModel(EndpointsModel):
  """ ProtoRPC Model for storing/retrieving a unit. """

  _message_fields_schema = ('id', 'uic', 'parent_id', 'branch_id', 'name')

  uic = ndb.StringProperty(required=True)
  parent_id = ndb.StringProperty(required=True, default=None)
  branch_id = ndb.StringProperty(required=True)
  name = ndb.StringProperty(required=True)
  abbreviated_name = ndb.StringProperty(default="")
  flagged = ndb.BooleanProperty(default=False)
  message = ndb.StringProperty(default="")
  unit_created_at = ndb.DateTimeProperty(auto_now_add=True)


class UnitsCollection(EndpointsModel):
  items = messages.MessageField(UnitsProtoModel, 1, repeated=True)

Error msg: `File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine- default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/util.py", line 170, in positional_wrapper

return wrapped(*args, **kwargs)

File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/messages.py", line 1531, in init

raise FieldDefinitionError('Invalid message class: %s' % message_type)

FieldDefinitionError: Invalid message class:

UnitsProtoModel<abbreviated_name=StringProperty('abbreviated_name', default=''),    branch_id=StringProperty('branch_id', required=True), flagged=BooleanProperty('flagged', default=False), message=StringProperty('message', default=''), name=StringProperty('name', required=True), owner=UserProperty('owner'), parent_id=StringProperty('parent_id', required=True), uic=StringProperty('uic', required=True), unit_created_at=DateTimeProperty('unit_created_at', auto_now_add=True)>`