Search code examples
google-cloud-datastoreapp-engine-ndb

Why is project id attached to my Datastore Key object?


For some inexplicable reason, my project id is attached to the Key of my User entity:

<Key('User', 5703358593630208), project=my-project-id>

This is giving me issues, such as when I am trying to use this same key as an ancestor of another entity — I would get this error:

google.cloud.ndb.exceptions.BadValueError: Expected Key instance, got <Key('User', 5703358593630208), project=my-project-id>

I created the User entity like this:

from google.cloud import datastore
datastore_client = datastore.Client()

def save_user(name):
    key = datastore_client.key('User')
    user = datastore.Entity(key=key)
    user.update({
        'name': name,
        'created': datetime.datetime.utcnow()
    })
    datastore_client.put(user)

Additional Example: Making an ancestral query

query = MyEntity.query(ancestor=user_key)

TypeError: ancestor must be a Key; received <Key('User', 5752652897976320), project=my-project-id>

What could be the explanation for this?


Solution

  • I believe the issue is that you are using both google.cloud.datastore and the NDB library and the key objects are not compatible. Here's an example of converting a datastore client key to an NDB key:

    from google.cloud import datastore
    from google.cloud import ndb
    
    # Start with a google.cloud.datastore key
    datastore_client = datastore.Client()
    datastore_key = datastore_client.key('Parent', 'foo', 'User', 1234)
    
    
    def key_to_ndb_key(key):
        # Use flat_path property to create an ndb_key
        key_path = key.flat_path
        ndb_key = ndb.Key(*key_path)
        return ndb_key
    
    
    # Convert to a ndb key
    ndb_client = ndb.Client()
    with ndb_client.context() as context:
        ndb_key = key_to_ndb_key(datastore_key)
        print(ndb_key)