Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ndb.OR operation in google app engine

I am Working on project where I need to do ndb.OR operation in Descending Order but for below code I am getting error like this:

BadRequestError: The first sort property must be the same as the property to which the inequality filter is applied. In your query the first sort property is TestNo but the inequality filter is on Math

class StudentMarks(ndb.Model):
    Math = ndb.IntegerProperty()
    Science = ndb.IntegerProperty()
    English = ndb.IntegerProperty()
    Social = ndb.IntegerProperty()
    TestNo = ndb.IntegerProperty()

@classmethod
def queryData(cls):
    return cls.query(ndb.OR(ndb.OR(cls.Math > 0, cls.Science > 0),
                     ndb.OR(cls.English > 0 , cls.Social > 0))).order(-cls.TestNo)

Is there any other way to implement this method.

like image 777
Yogeendra Avatar asked May 11 '26 15:05

Yogeendra


1 Answers

Without understanding your use case, I can come up with two ways.

  1. Sort in memory after the fact - this won't scale if you have thousands of entities.
  2. Use and AND clause and with TestNo as the first inequality filter (ie TestNo > -1 for instance) and the OR the second part of the AND clause.

Another approach may be changing or adding to the data stored so that you can use equality filters. It seems you are looking for various combinations of Math, Science, English etc.. that have a value greater than 0. Consider adding a ComputedProperty that stores a boolean of true of Math, Science etc is > 0, and false if == 0, then you could rewrite your query to something like the following. (I am using property name like hasMath for the computed property)

Computed Property would look like

hasMath = ndb.ComputedProperty(lambda self: self.Math > 0)    

Query would be

cls.query(ndb.OR(ndb.OR(cls.hasMath == True, cls.hasScience == True),
                 ndb.OR(cls.hasEnglish == True , cls.hasSocial == True))).order(-cls.TestNo)

Looking at your query further you could reduce the computed property to a single property to meet your query requirement.

 hasClass = ndb.ComputedProperty(lambda self: self.Math > 0 or self.Science > 0 or self.English > 0 or self.Social > 0)

The your query would be

 cls.query(cls.hasClass == True).order(-cls.TestNo)

Assuming this is the only query of this kind that you want to perform, this last option will be the best performing and least expensive in terms of indexes.

like image 112
Tim Hoffman Avatar answered May 14 '26 13:05

Tim Hoffman