views:

50

answers:

2

Hey everyone. I am using Appengine/Python and I haven't been able to fix a BadKeyError bug for the last 5 hours. I'm wondering if someone can help me figure it out. The part of the app that is causing the bug is a controller that processes votes done by users. Actor_id is the key of the user and object_id is the key of the object that is being voted on.

I've been testing the app by hiding and restoring some code, and I know for sure that the keys being received are good (first block), and that the entities are being created (second block). What does not work is creating an activity instance - raises BadKeyError (third block)

I've added the controller code, the model code, and the traceback of the error from the log page.

# Controller Code

class ActivityHandler(FacebookEnabled):
    def get(self):

        # i.e. fbid / headline id / upvote. This works
        actor_id = self.request.get('actor_id')
        object_id = self.request.get('object_id')

        # creating actor and object from keys (actor_id and object_id). 
        # This works.
        actor = models.Person.get(actor_id)
        object = models.Headline.get(object_id)
        logging.info("Actor " + str(actor) +": " + str(actor.name) +
           " object " + str(object) + ": " + str(object.title))

        # THIS IS WHAT SEEMS TO RAISE AN EXCEPTION
        activity = models.Activity(actor, object, action='upvote')
        activity.put()

# Model Code
class Activity(polymodel.PolyModel):
# User causing the action i.e. a person
    actor = db.ReferenceProperty(Person, required=True,
    collection_name='actors')

    # The object being the subject of the action i.e. headline
    object = db.ReferenceProperty(Headline, required=True,
        collection_name='objects')

    # The action being made
    action = db.StringProperty(required=True, choices=['upvote','downvote'],
         default='upvote')

Traceback

Name must be string type, not Headline
Traceback (most recent call last):
 File "/base/python_runtime/python_lib/versions/1/google/appengine/
ext/webapp/__init__.py", line 511, in __call__
   handler.get(*groups)
 File "/base/data/home/apps/libnentest/2.343063076026692316/main.py",
line 125, in get
   activity = models.Activity(actor, object, action='upvote')
 File "/base/python_runtime/python_lib/versions/1/google/appengine/
ext/db/__init__.py", line 726, in __init__
   key_name.__class__.__name__)
BadKeyError: Name must be string type, not Headline
+1  A: 

The constructor for PolyModel is like so: class PolyModel(parent=None, key_name=None, **kwds): So you're passing in the headline object as the key_name, which looks like it must be a string from the stacktrace.

From reading through the docs I think what you want to do is this:

activity_kwargs = {
    'actor' : actor,
    'object' : object',
    'action' : 'upvote',
}
activity = models.Activity(**activity_kwargs)
activity.put()

On a side note: Don't use object as a variable name, since it's a built-in keyword.

sdolan
I think it was the object thing. Thanks for noting this sdolan.
David Haddad
+2  A: 

object is always a poor choice of name and could well be causing the exception.

msw
Thanks. You're right. It's working now.
David Haddad