Reputation: 1
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
Upvotes: 0
Views: 927
Reputation: 21
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 :)
Upvotes: 0
Reputation: 9116
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
Upvotes: 4