4
votes

I am new with developing web applications with Google App Engine.

I wanted to check for entities in my datastore which have a null value set for a list property (db.ListProperty). However, when I tried to check anything against the entity.list GAE gives the error:

'super' object has no attribute 'list'.

After some search I saw in this SO question that setting an empty value for a list property of a GAE datastore entity is equivalent to not setting the property at all. This explains my error.

So I need to match entities in the datastore which do not have any list property set at all. Looking at the GAE documentation I still haven't found any method which allows me to check whether an entity has a particular property set.

NOTE: I don't have to do this with GQL. I can retrieve all entities with GQL, then check with python. But a GQL solution is also fine.

3
Can you post your model? Also according to the docs 'The value of a ListProperty cannot be None. It can, however, be an empty list. When None is specified for the default argument (or when the default argument is not specified), the default value of the property is the empty list.' I tried it and it does create the listproperty value as []. On the other hand, you cannot query to lists for equality so the only solution would be to query all the elements and filter them in python. - Sebastian Kreft
Yeah, by null value I meant empty lists. - Abhranil Das
I expect that you will have an empty 'list' element in the entity. I don't really understand why you'd have no list element at all, unless the entity was initially created by a Model that had no list element. - dragonx
If you follow the link in my question, you'll see that an empty list element is not stored at all in the gae datastore, even if the model had a list element, because of the way entities are stored. It's as good as not setting any attribute at all. - Abhranil Das

3 Answers

15
votes

I can think of three ways around this.

You're probably running into this situation because originally your model did not have a 'list' attribute, and you added one later, so you might have older instances in the datastore without the 'list' attribute. You can write a mapreduce function that goes through your datastore and ensures all entities have the 'list' element.

Otherwise, you can use the python hasattr function

if hasattr(entity, 'list'):
    a = entity.list[0] # or whatever operation you want

Thirdly, you can use an exception handler to catch the error case.

2
votes

There is no way to do this in GQL, which can only filter on existing values. Instead, you should use some form of computed property. NDB supports these, or you can override the _pre_put hook to have some other property set to be, for example, the length of the list. This will allow you to query on this new property == 0.

0
votes

what @dragonx wrote is completely fine. In my experience is better to use a try-except statement:

for q in query:
    try:
        q.someattribute
    except AttributeError:
        setattr(q, 'someattribute', True)  # or whatever operation you need