I pass an NDB Key() with a parent to a deferred function. In this function I retrieve the entity again. But I cannot use the passed key to get the entity directly. I have to change the key order pairing in the ndb.Key().

deferred.defer(my_deferred.a_function, entity.key)  

The entity.key() looks like :

Key('Parents', 'my_parent', 'Childs', 'my_child')    # the first pair is the parent?

my_deferred.py :

def a_function(key) :

    entity = ndb.Key(key)  # the pass entity.key does not work !!!!!

Giving exception : ValueError: Key() must have an even number of positional arguments.

    entity = ndb.Key('Childs', key.id(), parent = key.parent()).get() # this one works fine

I do not understand why the entity.key() method does not give me a key, which I can use directly? Or is there another way to get the entity, without "changing" the key. And I do not understand the ValueError excpetion.

Update : Thanks to Gregory

    entity = key.get()    # works fine
有帮助吗?

解决方案

first, answering your code specific question, passing the key properly, it is not a callable:

deferred.defer(my_deferred.a_function, entity.key)

next, on the actual design of the code itself, there are some things that need tweaking.

  • the deferred api serializes your code, so there really is no need to re-query entity from the datastore. if you insist on this though, passing the entity.key to the deferred method, it's already an instance of ndb.Key, so there's no need to construct a new Key object.

其他提示

I can't test this right now, but what about:

entity = ndb.Key(*key.flat())

The Key constructor accepts a few different kinds of input, and since flat() Returns a tuple of flattened kind and id values (kind1, id1, kind2, id2, ...)., unpacking the tuple should pass in the necessary inputs . Per the same link, this should also work:

entity = ndb.Key(pairs=key.pairs())
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top