Search code examples
pythongoogle-app-engineapp-engine-ndb

Google App Engine/NDB: "BadValueError: Expected Key, got None" for saving perfectly fine entity


I'm currently porting a web app to Google App Engine, Python 3, Standard Environment. (So I'm new to GAE and NDB).

I have a bug here that I don't understand. I obtain an entity like so, the adjust properties, then save.

sourceUsers = User.query().filter(User.email == request.form.get('sourceUserEmail')).fetch(1)
if sourceUsers:
    sourceUser = sourceUsers[0]
    # manipulation:
    sourceUser.sentInvitationSubscriptionKeys.append(subscription.key)
    # verify key:
    assert sourceUser.key != None
    sourceUser.put()

But the saving triggers the following traceback:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/yanone/Code/Google App Engine/typeworldappengine/main.py", line 500, in api
    sourceUser.put()
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/_options.py", line 89, in wrapper
    return wrapped(*pass_args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/utils.py", line 78, in wrapper
    return wrapped(*args, **new_kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/utils.py", line 109, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 4914, in _put
    return self._put_async(_options=kwargs["_options"]).result()
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/tasklets.py", line 190, in result
    self.check_success()
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/tasklets.py", line 137, in check_success
    raise self._exception
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/tasklets.py", line 312, in _advance_tasklet
    yielded = self.generator.send(send_value)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 4974, in put
    ds_entity = _entity_to_ds_entity(self)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 722, in _entity_to_ds_entity
    names = prop._to_datastore(entity, data)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 2063, in _to_datastore
    value = self._get_base_value_unwrapped_as_list(entity)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1551, in _get_base_value_unwrapped_as_list
    wrapped = self._get_base_value(entity)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1537, in _get_base_value
    return self._apply_to_values(entity, self._opt_call_to_base_type)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1834, in _apply_to_values
    value[:] = map(function, value)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1612, in _opt_call_to_base_type
    value = _BaseValue(self._call_to_base_type(value))
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1671, in _call_to_base_type
    return call(value)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 1801, in call
    new_value = method(self, value)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/ndb/model.py", line 3344, in _validate
    "Expected Key, got {!r}".format(value)
google.cloud.ndb.exceptions.BadValueError: Expected Key, got None

In the debugging, I even made sure that the entity has a key (assert sourceUser.key != None). So I really don't get it. What am I doing wrong?

Mind you, all other entities save fine. Just this one doesn't.

Thank you.


Solution

  • I dont think this entity's primary key is the problem. It's probably another Key field on the object.

    Whats the schema for the rest of you User object?