0
votes

I've a model named Conversation with some fields that includes date_created and date_updated as DateTimePropterty with auto_now_add and auto_now.

If I update the model using put() method, date_updated field is getting updated. But when I use the put_async method, the value in the date_updated field is not updating.

And I also have the test case using Python's unittest.Testcase, there it works fine.

Note: It works when I use put_async().get_result().

Sample model class:

class Conversation(ndb.Model):

   participants = ndb.StringProperty(repeated=True)  
   conversation_name = ndb.StringProperty()
   date_created = ndb.DateTimeProperty(required=True, auto_now_add=True)
   date_updated = ndb.DateTimeProperty(required=True, auto_now=True)

   @staticmethod
   def update_conversation_date_by_id(conversation_id):
       conversation = Conversation.get_by_id(conversation_id) if conversation_id else None
       if conversation is None:
           raise CannotFindEntity("Given conversation_id is not found")
       else:
           conversation.put_async().get
       return conversation
2

2 Answers

4
votes

If the request handler exits before the NDB put finishes the put might never happen.

class MyRequestHandler(webapp2.RequestHandler):
  def get(self):
    acct = Account.get_by_id(users.get_current_user().user_id())
    acct.view_counter += 1
    future = acct.put_async()
    # ...read something else from Datastore...
    template.render(...)
    future.get_result()

Try adding something like the last line in that codeblock to force it to wait.

In this example, it's a little silly to call future.get_result: the application never uses the result from NDB. That code is just in there to make sure that the request handler doesn't exit before the NDB put finishes; if the request handler exits too early, the put might never happen. As a convenience, you can decorate the request handler with @ndb.toplevel. This tells the handler not to exit until its asynchronous requests have finished. This in turn lets you send off the request and not worry about the result.

https://developers.google.com/appengine/docs/python/ndb/async

0
votes

the async methods stop executing when the main thread stops(request handler finishes)... so most likely your code doesnt execute. this can be prevented by adding @ndb.toplevel to your request handler. then the handler will wait for your async to complete.

https://developers.google.com/appengine/docs/python/ndb/async

async doesnt let you run code when the request handler is completed. async lets you run other (async) commands while waiting for async commands on the same request handler thread :)