Question

For my application we have users voting on issues, with separate datastores for votes and issues. I want the up and down vote totals to be updated whnever a user votes (or changes their original vote), which I'm trying to do by updating the issue transactionally within a Vote.Method. To do this, I have the transaction:

@ndb.transactional
def GetToChange(vote):
    key = ndb.Key('Issue', vote.IID)
    issue = key.get()
    return issue

Then, within the @Vote.Method I call the transactional function:

@Vote.method(request_fields=('UID', 'IID', 'Vote'), name='vote.add', path ='addvote')
def AddVote(self, vote):
   vote.put()
   i = GetToChange(vote)
   if newvote.Vote == True:
      i.UpTotal += 1
   if newvote.Vote == False:
      i.DownTotal += 1
   i.put()
   return vote

However, this always gives me a 503 error, and in the logs I spot "NoneType i has no attribute UpTotal", which suggests the entity isn't being retrieved. What am I doing wrong?

Edit: More details This @Vote.method takes a user ID (UID), Issue ID (the ID of an issue in the Issue datastore), and a boolean 'Vote' in the request. The vote is stored with vote.put(). I then call my transactional method to retrieve the issue using the IID from the request. I've added more to the code to show what I'm trying to do with the issue.

Was it helpful?

Solution

Right, sorted! The problem was to do with the IID property I was using in the Vote model, which is why it was never able to retrieve the correct issue.

In the vote model, I changed the IID to ndb.KeyProperty(kind=Issue). Trying to use the integer ID from the datastore didn't work though; as I commented above, this gave a ProtocolBufferDecodeError "corrupted". However, passing the 64bit entitykey in the request works! So, now the API uses the entityKey helper property with Issues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top