joplaete
joplaete

Reputation: 113

ndb ComputedProperty filtering

I have a User ndb.Model which has a username StringProperty that allows upper en lower case letters, at some point I wanted to fetch users by username but have the case forced to lowercase for the filtering. Therefor I added a ComputedProperty to User: username_lower which returns the lowercase version of the username as follows:

    @ndb.ComputedProperty
    def username_lower(self):
        return self.username.lower()

then I filter the query like so:

    query = query.filter(User.username_lower==username_input.lower())

This works, however it only does for users created (put) after I added this to the model. Users created before don't get filtered by this query. I first thought the ComputedProperty wasn't working for the older users. However, tried this and calling .username_lower on an old user does work.

Finally, I found a solution to this is to fetch all users and just run a .put_multi(all_users)

So seems like a ComputedProperty added later to the model works when you invoke it straight but doesn't filter at first. Does it not get indexed automatically ? or could it be a caching thing.. ?

any insight to why it was behaving like this would be welcome

thanks

Upvotes: 2

Views: 477

Answers (1)

lecstor
lecstor

Reputation: 5707

this is the expected behaviour. The value of a ComputedProperty (or any property for that matter I guess) is indexed when the object is "put". The datastore does not do automatic schema updates or anything like that. When you update your schema you need to either allow for different schema versions in your code or update your entities individually. In the case of changes to indexing you have no choice but to update your entities. The MapReduce API can be used for updating entities to avoid request limitations and the like.

Upvotes: 4

Related Questions