Python google.appengine.ext.ndb.Model() Examples

The following are 30 code examples of google.appengine.ext.ndb.Model(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module google.appengine.ext.ndb , or try the search function .
Example #1
Source File: monotonic_test.py    From luci-py with Apache License 2.0 6 votes vote down vote up
def test_store_new_version_extra(self):
    # Includes an unrelated entity in the PUT. It must be in the same entity
    # group.
    cls = monotonic.get_versioned_root_model('fidoula')
    parent = ndb.Key(cls, 'foo')
    class Unrelated(ndb.Model):
      b = ndb.IntegerProperty()
    unrelated = Unrelated(id='bar', parent=parent, b=42)
    actual = monotonic.store_new_version(
        EntityX(a=1, parent=parent), cls, extra=[unrelated])
    self.assertEqual(
        ndb.Key('fidoula', 'foo', 'EntityX', monotonic.HIGH_KEY_ID), actual)
    actual = monotonic.store_new_version(EntityX(a=2, parent=parent), cls)
    self.assertEqual(
        ndb.Key('fidoula', 'foo', 'EntityX', monotonic.HIGH_KEY_ID - 1), actual)
    self.assertEqual({'b': 42}, unrelated.key.get().to_dict()) 
Example #2
Source File: snippets.py    From python-docs-samples with Apache License 2.0 6 votes vote down vote up
def query_purchase_with_customer_key():
    # [START purchase_with_customer_key_models]
    class Customer(ndb.Model):
        name = ndb.StringProperty()

    class Purchase(ndb.Model):
        customer = ndb.KeyProperty(kind=Customer)
        price = ndb.IntegerProperty()
    # [END purchase_with_customer_key_models]

    def query_purchases_for_customer_via_key(customer_entity):
        purchases = Purchase.query(
            Purchase.customer == customer_entity.key).fetch()
        return purchases

    return Customer, Purchase, query_purchases_for_customer_via_key 
Example #3
Source File: snippets.py    From python-docs-samples with Apache License 2.0 6 votes vote down vote up
def query_purchase_with_ancestor_key():
    # [START purchase_with_ancestor_key_models]
    class Customer(ndb.Model):
        name = ndb.StringProperty()

    class Purchase(ndb.Model):
        price = ndb.IntegerProperty()
    # [END purchase_with_ancestor_key_models]

    def create_purchase_for_customer_with_ancestor(customer_entity):
        purchase = Purchase(parent=customer_entity.key)
        return purchase

    def query_for_purchases_of_customer_with_ancestor(customer_entity):
        purchases = Purchase.query(ancestor=customer_entity.key).fetch()
        return purchases

    return (Customer, Purchase,
            create_purchase_for_customer_with_ancestor,
            query_for_purchases_of_customer_with_ancestor) 
Example #4
Source File: snippets.py    From python-docs-samples with Apache License 2.0 6 votes vote down vote up
def create_entity_with_parent_keys():
    account_key = ndb.Key(Account, 'sandy@example.com')

    # Ask Datastore to allocate an ID.
    new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]

    # Datastore returns us an integer ID that we can use to create the message
    # key
    message_key = ndb.Key('Message', new_id, parent=account_key)

    # Now we can put the message into Datastore
    initial_revision = Revision(
        message_text='Hello', id='1', parent=message_key)
    initial_revision.put()

    return initial_revision 
Example #5
Source File: input_readers.py    From locality-sensitive-hashing with MIT License 6 votes vote down vote up
def _validate_filters_ndb(cls, filters, model_class):
    """Validate ndb.Model filters."""
    if not filters:
      return

    properties = model_class._properties

    for f in filters:
      prop, _, val = f
      if prop not in properties:
        raise errors.BadReaderParamsError(
            "Property %s is not defined for entity type %s",
            prop, model_class._get_kind())

      # Validate the value of each filter. We need to know filters have
      # valid value to carry out splits.
      try:
        properties[prop]._do_validate(val)
      except db.BadValueError, e:
        raise errors.BadReaderParamsError(e) 
Example #6
Source File: datastore_test.py    From python-docs-samples with Apache License 2.0 6 votes vote down vote up
def testEventuallyConsistentGlobalQueryResult(self):
        class TestModel(ndb.Model):
            pass

        user_key = ndb.Key('User', 'ryan')

        # Put two entities
        ndb.put_multi([
            TestModel(parent=user_key),
            TestModel(parent=user_key)
        ])

        # Global query doesn't see the data.
        self.assertEqual(0, TestModel.query().count(3))
        # Ancestor query does see the data.
        self.assertEqual(2, TestModel.query(ancestor=user_key).count(3))
# [END HRD_example_1]

    # [START HRD_example_2] 
Example #7
Source File: appengine.py    From splunk-ref-pas-code with Apache License 2.0 6 votes vote down vote up
def __init__(self, model, key_name, property_name, cache=None, user=None):
    """Constructor for Storage.

    Args:
      model: db.Model or ndb.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is a CredentialsProperty
        or CredentialsNDBProperty.
      cache: memcache, a write-through cache to put in front of the datastore.
        If the model you are using is an NDB model, using a cache will be
        redundant since the model uses an instance cache and memcache for you.
      user: users.User object, optional. Can be used to grab user ID as a
        key_name if no key name is specified.
    """
    if key_name is None:
      if user is None:
        raise ValueError('StorageByKeyName called with no key name or user.')
      key_name = user.user_id()

    self._model = model
    self._key_name = key_name
    self._property_name = property_name
    self._cache = cache 
Example #8
Source File: model_datastore_input_reader.py    From locality-sensitive-hashing with MIT License 6 votes vote down vote up
def _validate_filters_ndb(cls, filters, model_class):
    """Validate ndb.Model filters."""
    if not filters:
      return

    properties = model_class._properties

    for f in filters:
      prop, _, val = f
      if prop not in properties:
        raise errors.BadReaderParamsError(
            "Property %s is not defined for entity type %s",
            prop, model_class._get_kind())

      # Validate the value of each filter. We need to know filters have
      # valid value to carry out splits.
      try:
        properties[prop]._do_validate(val)
      except db.BadValueError, e:
        raise errors.BadReaderParamsError(e) 
Example #9
Source File: datastore_test.py    From python-docs-samples with Apache License 2.0 6 votes vote down vote up
def testDeterministicOutcome(self):
        # 50% chance to apply.
        self.policy.SetProbability(.5)
        # Use the pseudo random sequence derived from seed=2.
        self.policy.SetSeed(2)

        class TestModel(ndb.Model):
            pass

        TestModel().put()

        self.assertEqual(0, TestModel.query().count(3))
        self.assertEqual(0, TestModel.query().count(3))
        # Will always be applied before the third query.
        self.assertEqual(1, TestModel.query().count(3))
    # [END HRD_example_2]


# [START main] 
Example #10
Source File: appengine.py    From sndlatr with Apache License 2.0 6 votes vote down vote up
def __init__(self, model, key_name, property_name, cache=None, user=None):
    """Constructor for Storage.

    Args:
      model: db.Model or ndb.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is a CredentialsProperty
        or CredentialsNDBProperty.
      cache: memcache, a write-through cache to put in front of the datastore.
        If the model you are using is an NDB model, using a cache will be
        redundant since the model uses an instance cache and memcache for you.
      user: users.User object, optional. Can be used to grab user ID as a
        key_name if no key name is specified.
    """
    if key_name is None:
      if user is None:
        raise ValueError('StorageByKeyName called with no key name or user.')
      key_name = user.user_id()

    self._model = model
    self._key_name = key_name
    self._property_name = property_name
    self._cache = cache 
Example #11
Source File: appengine.py    From luci-py with Apache License 2.0 6 votes vote down vote up
def _is_ndb(self):
        """Determine whether the model of the instance is an NDB model.

        Returns:
            Boolean indicating whether or not the model is an NDB or DB model.
        """
        # issubclass will fail if one of the arguments is not a class, only
        # need worry about new-style classes since ndb and db models are
        # new-style
        if isinstance(self._model, type):
            if ndb is not None and issubclass(self._model, ndb.Model):
                return True
            elif issubclass(self._model, db.Model):
                return False

        raise TypeError('Model class not an NDB or DB model: %s.' %
                        (self._model,)) 
Example #12
Source File: msgprop.py    From datastore-ndb-python with Apache License 2.0 6 votes vote down vote up
def _message_to_entity(msg, modelclass):
  """Recursive helper for _to_base_type() to convert a message to an entity.

  Args:
    msg: A Message instance.
    modelclass: A Model subclass.

  Returns:
    An instance of modelclass.
  """
  ent = modelclass()
  for prop_name, prop in modelclass._properties.iteritems():
    if prop._code_name == 'blob_':  # TODO: Devise a cleaner test.
      continue  # That's taken care of later.
    value = getattr(msg, prop_name)
    if value is not None and isinstance(prop, model.StructuredProperty):
      if prop._repeated:
        value = [_message_to_entity(v, prop._modelclass) for v in value]
      else:
        value = _message_to_entity(value, prop._modelclass)
    setattr(ent, prop_name, value)
  return ent 
Example #13
Source File: appengine.py    From earthengine with MIT License 6 votes vote down vote up
def __init__(self, model, key_name, property_name, cache=None, user=None):
    """Constructor for Storage.

    Args:
      model: db.Model or ndb.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is a CredentialsProperty
        or CredentialsNDBProperty.
      cache: memcache, a write-through cache to put in front of the datastore.
        If the model you are using is an NDB model, using a cache will be
        redundant since the model uses an instance cache and memcache for you.
      user: users.User object, optional. Can be used to grab user ID as a
        key_name if no key name is specified.
    """
    if key_name is None:
      if user is None:
        raise ValueError('StorageByKeyName called with no key name or user.')
      key_name = user.user_id()

    self._model = model
    self._key_name = key_name
    self._property_name = property_name
    self._cache = cache 
Example #14
Source File: sharding.py    From luci-py with Apache License 2.0 6 votes vote down vote up
def shard_key(key, number_of_letters, root_entity_type):
  """Returns an ndb.Key to a virtual entity of type |root_entity_type|.

  This key is to be used as an entity group for database sharding. Transactions
  can be done over this group. Note that this sharding root entity doesn't have
  to ever exist in the database.

  Arguments:
    key: full key to take a subset of. It must be '[0-9a-f]+'. It is assumed
        that this key is well distributed, if not, use hashed_shard_key()
        instead. This means the available number of buckets is done in
        increments of 4 bits, e.g. 16, 256, 4096, 65536.
    number_of_letters: number of letters to use from |key|. key length must be
        encoded through an out-of-band mean and be constant.
    root_entity_type: root entity type. It can be either a reference to a
        ndb.Model class or just a string.
  """
  assert _HEX.issuperset(key), key
  assert isinstance(key, str) and len(key) >= number_of_letters, repr(key)
  # number_of_letters==10 means 1099511627776 shards, which is unreasonable.
  assert 1 <= number_of_letters < 10, number_of_letters
  assert isinstance(root_entity_type, (ndb.Model, str)) and root_entity_type, (
      root_entity_type)
  return ndb.Key(root_entity_type, key[:number_of_letters]) 
Example #15
Source File: monotonic.py    From luci-py with Apache License 2.0 6 votes vote down vote up
def get_versioned_most_recent_with_root_async(cls, root_key):
  """Returns the most recent instance of a versioned entity and the root entity.

  Getting the root entity is needed to get the current index.
  """
  # Using a cls.query(ancestor=root_key).get() would work too but is less
  # efficient since it can't be cached by ndb's cache.
  assert not ndb.in_transaction()
  assert issubclass(cls, ndb.Model), cls
  assert root_key is None or isinstance(root_key, ndb.Key), root_key

  root = root_key.get()
  if not root or not root.current:
    raise ndb.Return(None, None)
  entity = yield ndb.Key(cls, root.current, parent=root_key).get_async()
  raise ndb.Return(root, entity) 
Example #16
Source File: input_readers.py    From browserscope with Apache License 2.0 6 votes vote down vote up
def _validate_filters_ndb(cls, filters, model_class):
    """Validate ndb.Model filters."""
    if not filters:
      return

    properties = model_class._properties

    for f in filters:
      prop, _, val = f
      if prop not in properties:
        raise errors.BadReaderParamsError(
            "Property %s is not defined for entity type %s",
            prop, model_class._get_kind())

      # Validate the value of each filter. We need to know filters have
      # valid value to carry out splits.
      try:
        properties[prop]._do_validate(val)
      except db.BadValueError, e:
        raise errors.BadReaderParamsError(e) 
Example #17
Source File: appengine.py    From billing-export-python with Apache License 2.0 6 votes vote down vote up
def __init__(self, model, key_name, property_name, cache=None, user=None):
    """Constructor for Storage.

    Args:
      model: db.Model or ndb.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is a CredentialsProperty
        or CredentialsNDBProperty.
      cache: memcache, a write-through cache to put in front of the datastore.
        If the model you are using is an NDB model, using a cache will be
        redundant since the model uses an instance cache and memcache for you.
      user: users.User object, optional. Can be used to grab user ID as a
        key_name if no key name is specified.
    """
    if key_name is None:
      if user is None:
        raise ValueError('StorageByKeyName called with no key name or user.')
      key_name = user.user_id()

    self._model = model
    self._key_name = key_name
    self._property_name = property_name
    self._cache = cache 
Example #18
Source File: msgprop.py    From datastore-ndb-python with Apache License 2.0 6 votes vote down vote up
def _from_base_type(self, ent):
    """Convert a Model instance (entity) to a Message value."""
    if ent._projection:
      # Projection query result.  Reconstitute the message from the fields.
      return _projected_entity_to_message(ent, self._message_type)

    blob = ent.blob_
    if blob is not None:
      protocol = self._protocol_impl
    else:
      # Perhaps it was written using a different protocol.
      protocol = None
      for name in _protocols_registry.names:
        key = '__%s__' % name
        if key in ent._values:
          blob = ent._values[key]
          if isinstance(blob, model._BaseValue):
            blob = blob.b_val
          protocol = _protocols_registry.lookup_by_name(name)
          break
    if blob is None or protocol is None:
      return None  # This will reveal the underlying dummy model.
    msg = protocol.decode_message(self._message_type, blob)
    return msg 
Example #19
Source File: appengine.py    From googleapps-message-recall with Apache License 2.0 6 votes vote down vote up
def __init__(self, model, key_name, property_name, cache=None, user=None):
    """Constructor for Storage.

    Args:
      model: db.Model or ndb.Model, model class
      key_name: string, key name for the entity that has the credentials
      property_name: string, name of the property that is a CredentialsProperty
        or CredentialsNDBProperty.
      cache: memcache, a write-through cache to put in front of the datastore.
        If the model you are using is an NDB model, using a cache will be
        redundant since the model uses an instance cache and memcache for you.
      user: users.User object, optional. Can be used to grab user ID as a
        key_name if no key name is specified.
    """
    if key_name is None:
      if user is None:
        raise ValueError('StorageByKeyName called with no key name or user.')
      key_name = user.user_id()

    self._model = model
    self._key_name = key_name
    self._property_name = property_name
    self._cache = cache 
Example #20
Source File: types.py    From graphene-gae with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def is_type_of(cls, root, info):
        if isinstance(root, cls):
            return True

        if not isinstance(root, ndb.Model):
            raise Exception(('Received incompatible instance "{}".').format(root))

        # Returns True if `root` is a PolyModel subclass and `cls` is in the
        # class hierarchy of `root` which is retrieved with `_class_key`
        if (hasattr(root, '_class_key') and
            hasattr(cls._meta.model, '_class_key') and
            set(cls._meta.model._class_key()).issubset(
                set(root._class_key()))):
            return True

        return type(root) == cls._meta.model 
Example #21
Source File: serializable_test.py    From luci-py with Apache License 2.0 5 votes vote down vote up
def test_repeated_properties(self):
    """Test that properties with repeated=True are handled."""
    class IntsEntity(ndb.Model, serializable.SerializableModelMixin):
      ints = ndb.IntegerProperty(repeated=True)
    class DatesEntity(ndb.Model, serializable.SerializableModelMixin):
      dates = ndb.DateTimeProperty(repeated=True)

    # Same point in time as datetime and as timestamp.
    dt = datetime.datetime(2012, 1, 2, 3, 4, 5)
    ts = 1325473445000000

    # Repeated properties that are not set are converted to empty lists.
    self.assertEqual({'ints': []}, IntsEntity().to_serializable_dict())
    self.assertEqual({'dates': []}, DatesEntity().to_serializable_dict())

    # List of ints works (as an example of simple repeated property).
    self.assertEqual(
        {'ints': [1, 2]},
        IntsEntity(ints=[1, 2]).to_serializable_dict())
    self.assertEqual(
        {'ints': [1, 2]},
        IntsEntity.convert_serializable_dict({'ints': [1, 2]}))

    # List of datetimes works (as an example of not-so-simple property).
    self.assertEqual(
        {'dates': [ts, ts]},
        DatesEntity(dates=[dt, dt]).to_serializable_dict())
    self.assertEqual(
        {'dates': [dt, dt]},
        DatesEntity.convert_serializable_dict({'dates': [ts, ts]})) 
Example #22
Source File: serializable_test.py    From luci-py with Apache License 2.0 5 votes vote down vote up
def _test_structured_properties_class(self, structured_cls):
    """Common testing for StructuredProperty and LocalStructuredProperty."""
    # Plain ndb.Model.
    class InnerSimple(ndb.Model):
      a = ndb.IntegerProperty()

    # With SerializableModelMixin.
    class InnerSmart(ndb.Model, serializable.SerializableModelMixin):
      serializable_properties = {
        'a': serializable.READABLE | serializable.WRITABLE,
      }
      a = ndb.IntegerProperty()
      b = ndb.IntegerProperty()

    class Outter(ndb.Model, serializable.SerializableModelMixin):
      simple = structured_cls(InnerSimple)
      smart = structured_cls(InnerSmart)

    # InnerSimple gets serialized entirely, while only readable fields
    # on InnerSmart are serialized.
    entity = Outter()
    entity.simple = InnerSimple(a=1)
    entity.smart = InnerSmart(a=2, b=3)
    self.assertEqual(
        {'simple': {'a': 1}, 'smart': {'a': 2}},
        entity.to_serializable_dict())

    # Works backwards as well. Note that 'convert_serializable_dict' returns
    # a dictionary that can be fed to entity's 'populate' or constructor. Entity
    # by itself is smart enough to transform subdicts into structured
    # properties.
    self.assertEqual(
        Outter(simple=InnerSimple(a=1), smart=InnerSmart(a=2)),
        Outter.from_serializable_dict({'simple': {'a': 1}, 'smart': {'a': 2}})) 
Example #23
Source File: serializable_test.py    From luci-py with Apache License 2.0 5 votes vote down vote up
def test_exclude_works(self):
    """|exclude| argument of to_serializable_dict() is respected."""
    class Entity(ndb.Model, serializable.SerializableModelMixin):
      prop1 = ndb.IntegerProperty()
      prop2 = ndb.IntegerProperty()
      prop3 = ndb.IntegerProperty()

    entity = Entity(prop1=1, prop2=2, prop3=3)
    self.assertEqual(
        {'prop1': 1, 'prop3': 3},
        entity.to_serializable_dict(exclude=['prop2'])) 
Example #24
Source File: serializable_test.py    From luci-py with Apache License 2.0 5 votes vote down vote up
def test_from_serializable_dict_kwargs_work(self):
    """Keyword arguments in from_serializable_dict are passed to constructor."""
    class Entity(ndb.Model, serializable.SerializableModelMixin):
      prop = ndb.IntegerProperty()

    # Pass entity key via keyword parameters.
    entity = Entity.from_serializable_dict(
        {'prop': 123}, id='my id', parent=ndb.Key('Fake', 'parent'))
    self.assertEqual(123, entity.prop)
    self.assertEqual(ndb.Key('Fake', 'parent', 'Entity', 'my id'), entity.key) 
Example #25
Source File: shopping_cart.py    From python-docs-samples with Apache License 2.0 5 votes vote down vote up
def iterate_over_query_results_in_tasklet(Model, is_the_entity_i_want):
    qry = Model.query()
    qit = qry.iter()
    while (yield qit.has_next_async()):
        entity = qit.next()
        # Do something with entity
        if is_the_entity_i_want(entity):
            raise ndb.Return(entity) 
Example #26
Source File: msgprop.py    From datastore-ndb-python with Apache License 2.0 5 votes vote down vote up
def _projected_entity_to_message(ent, message_type):
  """Recursive helper for _from_base_type() to convert an entity to a message.

  Args:
    ent: A Model instance.
    message_type: A Message subclass.

  Returns:
    An instance of message_type.
  """
  msg = message_type()
  analyzed = _analyze_indexed_fields(ent._projection)
  for name, sublist in analyzed.iteritems():
    prop = ent._properties[name]
    val = prop._get_value(ent)
    assert isinstance(prop, model.StructuredProperty) == bool(sublist)
    if sublist:
      field = message_type.field_by_name(name)
      assert isinstance(field, messages.MessageField)
      assert prop._repeated == field.repeated
      if prop._repeated:
        assert isinstance(val, list)
        val = [_projected_entity_to_message(v, field.type) for v in val]
      else:
        assert isinstance(val, prop._modelclass)
        val = _projected_entity_to_message(val, field.type)
    setattr(msg, name, val)
  return msg 
Example #27
Source File: msgprop.py    From datastore-ndb-python with Apache License 2.0 5 votes vote down vote up
def _to_base_type(self, msg):
    """Convert a Message value to a Model instance (entity)."""
    ent = _message_to_entity(msg, self._modelclass)
    ent.blob_ = self._protocol_impl.encode_message(msg)
    return ent 
Example #28
Source File: ndb.py    From googleapps-message-recall with Apache License 2.0 5 votes vote down vote up
def model_form(model, base_class=Form, only=None, exclude=None, field_args=None,
               converter=None):
    """
    Creates and returns a dynamic ``wtforms.Form`` class for a given
    ``ndb.Model`` class. The form class can be used as it is or serve as a base
    for extended form classes, which can then mix non-model related fields,
    subforms with other model forms, among other possibilities.

    :param model:
        The ``ndb.Model`` class to generate a form for.
    :param base_class:
        Base form class to extend from. Must be a ``wtforms.Form`` subclass.
    :param only:
        An optional iterable with the property names that should be included in
        the form. Only these properties will have fields.
    :param exclude:
        An optional iterable with the property names that should be excluded
        from the form. All other properties will have fields.
    :param field_args:
        An optional dictionary of field names mapping to keyword arguments
        used to construct each field object.
    :param converter:
        A converter to generate the fields based on the model properties. If
        not set, ``ModelConverter`` is used.
    """
    # Extract the fields from the model.
    field_dict = model_fields(model, only, exclude, field_args, converter)

    # Return a dynamically created form class, extending from base_class and
    # including the created fields as properties.
    return type(model._get_kind() + 'Form', (base_class,), field_dict) 
Example #29
Source File: appengine.py    From googleapps-message-recall with Apache License 2.0 5 votes vote down vote up
def _is_ndb(self):
    """Determine whether the model of the instance is an NDB model.

    Returns:
      Boolean indicating whether or not the model is an NDB or DB model.
    """
    # issubclass will fail if one of the arguments is not a class, only need
    # worry about new-style classes since ndb and db models are new-style
    if isinstance(self._model, type):
      if ndb is not None and issubclass(self._model, ndb.Model):
        return True
      elif issubclass(self._model, db.Model):
        return False

    raise TypeError('Model class not an NDB or DB model: %s.' % (self._model,)) 
Example #30
Source File: test_converter.py    From graphene-gae with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def testKeyProperty_withSuffix_required(self):
        class User(ndb.Model):
            name = ndb.StringProperty()

        my_registry = Registry()

        class UserType(NdbObjectType):
            class Meta:
                model = User
                registry = my_registry

        prop = ndb.KeyProperty(kind='User', required=True)
        prop._code_name = 'user_key'

        conversion = convert_ndb_property(prop, my_registry)

        self.assertLength(conversion, 2)

        self.assertEqual(conversion[0].name, 'user_id')
        self.assertIsInstance(conversion[0].field, DynamicNdbKeyStringField)
        _type = conversion[0].field.get_type()
        self.assertIsInstance(_type, NdbKeyStringField)
        self.assertIsInstance(_type._type, NonNull)
        self.assertEqual(_type._type.of_type, String)

        self.assertEqual(conversion[1].name, 'user')
        self.assertIsInstance(conversion[1].field, DynamicNdbKeyReferenceField)
        _type = conversion[1].field.get_type()
        self.assertIsInstance(_type, NdbKeyReferenceField)
        self.assertIsInstance(_type._type, NonNull)
        self.assertEqual(_type._type.of_type, UserType)