Cranjis
Cranjis

Reputation: 1960

can't update datastore in google-apps-engine

I created a datastore object similarly to the guestbook tutorial:

class myDS(ndb.Model):
    a = ndb.StringProperty(indexed=True)

And I have an Handlers to access it and update is:

class Handler1:

    my_ds = myDS()
    my_ds.a = "abc" #Trying to update the value

class Handler2:
    my_ds = myDS()
    self.response.write(my_ds.a) #Trying to access my_ds.aafter it was updated in Handlers1

def main():
   application = webapp.WSGIApplication([
           ('/set',   Handler1),
           ('/get',   Handler2])

I call:

Myapp.com/set 
Myapp.com/get : Prints None (Didn't update to "abc")

Why wasn't the value of a updated? How can I update across the handlers?

Upvotes: 0

Views: 84

Answers (1)

Dan Cornilescu
Dan Cornilescu

Reputation: 39814

The first thing to note is that in Handler1 your code doesn't actually save the entity to the datastore, for that you need to invoke the .put() method:

my_ds = myDS()
my_ds.a = "abc" #Trying to update the value
my_ds_key = my_ds.put()  # save my_ds to the datastore and get its key

The second thing to note is that in Handler2 the my_ds = myDS() call doesn't retrieve an entity from the datastore as you might expect, it just creates a new entity instead (which is also not saved to the datastore). To retrieve an entity from the datastore you need to do a lookup by the entity's key (or obtain it via a query):

my_ds = my_ds_key.get()

These are very basic concepts about using the datastore, you probably need to get more familiar with them. You should go through Creating, Retrieving, Updating, and Deleting Entities (and maybe other related chapters grouped under the Google Cloud Datastore section in the left side navigation bar in that doc page)

Finally, to be able to make such lookup you need to somehow be able to determine or transfer the entity key obtained in Handler1 to Handler2 as each request to these handlers is independent from each-other. Possibly of interest: Passing data between pages in a redirect() function in Google App Engine

Example of passing the key's string representation via webapp2 sessions:

In Handler1

my_ds_key = my_ds.put()  # save my_ds to the datastore and get its key
self.session['urlsafe'] = my_ds_key.urlsafe()

In Handler2

urlsafe = self.session.get('urlsafe')
if urlsafe:        
    my_ds = ndb.Key(urlsafe=urlsafe).get()

Example of passing the key's string representation using a URL query string like /get?urlsafe=<key's urlsafe representation> (maybe hashed if you want, as it will be visible in the browser):

In Handler1

my_ds_key = my_ds.put()  # save my_ds to the datastore and get its key
self.redirect('/get?urlsafe=%s' % my_ds_key.urlsafe())

In Handler2

urlsafe = self.request.get('urlsafe')
if urlsafe:        
    my_ds = ndb.Key(urlsafe=urlsafe).get()

Example of getting the entity in Handler2 via a query (the example assumes the right entity is returned by the query)

results = myDS().query().fetch(limit=1)
if results:
    my_ds = results[0]

Upvotes: 3

Related Questions