pythongoogle-app-enginegoogle-cloud-datastoreeager-loadingpyamf

GAE datastore eager loading in python api


I have two models in relation one-to-many:

class Question(db.Model):

questionText = db.StringProperty(multiline=False)

class Answer(db.Model):

answerText = db.StringProperty(multiline=False)

question = db.ReferenceProperty(Question, collection_name='answers')

I have front-end implemented in Flex and use pyamf to load data.

When i try to load all answers with related questions all works as desired and I can access field

answer.question

however in case of loading questions (e.g. by Questions.all() ), 'question.answers' remains empty/null

(though on server/python side I can revise question.answers without problem - probably after lazy-loading).

So is it possible to load all questions along with answers ?

(I know this is possible in JPA Java api but what about python ?)

Shoud I use additional setting, GQL query or django framework to make it work ?


Solution

  • By default PyAMF will not encode ReferenceProperty fields unless they have already been specifically loaded by the service method. This is on purpose so you don't end up encoding more than you have to.

    PyAMF looks for a special class attribute __amf__ which it uses to customise the encoding and decoding process for instances of that type. More information can be found in the docs.

    So, to force the encoding of all answers for all questions you should be able to do:

    class Question(db.Model):
        class __amf__:
            static = ('answers',)
    
        questionText = db.StringProperty(multiline=False)
    
    class Answer(db.Model):
        answertText = db.StringProperty(multiline=False)
        question = db.ReferenceProperty(Question, collection_name='answers')
    

    Setting the static attribute will ensure that every Question instance has the answers attribute set (via getattr) which will in turn to the datastore lookup that you require.

    It is important to not that this setting is application wide, so any question will have an answers attribute as it appears on the instance.