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.
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.