Search code examples
pythongoogle-app-enginegoogle-cloud-platformgoogle-cloud-datastoregoogle-app-engine-python

appengine: ReferencePropertyResolveError: ReferenceProperty failed to be resolved: [u'User', xxxxxxxxxxxxx]


I have code to fetch participants and display them. The logic that controls the view is below:

    def fetch_participants(self, count=12):
        memcache_key = 'mission_participants:%d:%d' % (self.key().id(), count)
        participants = utils.deserialize_entities(memcache.get(memcache_key))
        if participants is None:
            participants = self.fetch_participants_datastore(count)
            memcache.set(memcache_key, utils.serialize_entities(participants), 3600)
        return participants

The problem is that appengine is throwing the following error:

  File "site/templates/participant_base.html", line 209, in block "content"
    {% set participants = mission.fetch_participants(40) %}
  File "/base/data/home/apps/proj/32.424491487021355902/models/mission.py", line 311, in fetch_participants
    participants = self.fetch_participants_datastore(count)
  File "/base/data/home/apps/proj/32.424491487021355902/models/mission.py", line 301, in fetch_participants_datastore
    users = [join.user for join in joins]
  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/9fae800fb98bd45d/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 3734, in __get__
    reference_id.to_path())
ReferencePropertyResolveError: ReferenceProperty failed to be resolved: [u'User', xxxxxxxxxxx]

The error appears to be this line:

participants = self.fetch_participants_datastore(count)

A user on stackoverflow has asked a simmilar question:

https://stackoverflow.com/a/9835787/10543735

This happens when you attempt to resolve a reference property (by dereferencing it - for instance, (MyModel.MyReferenceProp.foo), and the property being referenced no longer exists - because it has been deleted.

You need to modify your code to catch this exception when you dereference an entity that may have been deleted, and handle it appropriately.

I am thinking i have to do something similar, problem is am do not know how to modify the code to catch the exception. Is thee a way to filter the participants to not include the referenced participants? Is there a better alternative?

def fetch_participants_datastore(self, count=12):
    joins = self.mission_joins.order('-created').fetch(count * 2)
    utils.prefetch_refprops(joins, MissionJoin.user)
    users = [join.user for join in joins]
    with_avatars = [user for user in users if user.has_avatar()]
    without_avatars = [user for user in users if not user.has_avatar()]
    users = with_avatars + without_avatars
    return users[:count]

Edit:

for join in joins:
     try:
          users = join.user
     except:
          pass

Solution

  • Break line 301 of your code into a for loop and add a try/except block around the line with join.user