views:

177

answers:

2

I think I'm overlooking something simple here, I can't imagine this is impossible to do.

I want to filter by a datetime attribute and then order the result by a ranking integer attribute. When I try to do this:

query.filter("submitted >=" thisweek).order("ranking")

I get the following:

BadArgumentError: First ordering property must be the same as inequality filter property, if specified for this query; received ranking, expected submitted

Huh? What am I missing?

Thanks.

+5  A: 

The datastore isn't capable of ordering a query that contains an inequality by any property other than the one used in the inequality.

This can often be worked around by adding a property that can be filtered with an equality; in this case, it may be possible to have a BooleanProperty tracking whether an entity is from the current week, and update it for all entities at the end of each week.

Wooble
Thanks. How could I write something to update my entire datastore if all my requests must only take 10 seconds?
dave paola
30 seconds, not 10, and you can use something like this: http://blog.notdot.net/2010/03/Announcing-a-robust-datastore-bulk-update-utility-for-App-Engine
Nick Johnson
Nick: That looks really, really useful. Thanks a lot.
dave paola
+1  A: 

I used another trick, which worked out simply because of the format I needed my data in (a list of dicts). In this case I run the datetime-based query, create dicts from the returned ents, and then sort by the numeric 'counter' property. Reversing the sort gave me a descending order. Keep in mind I only requested 10 results, on a fairly small datastore.

q = food.Food.all()
q.filter("last_modified <=", now)
q.filter("last_modified >=", hour_ago)

ents = q.fetch(10)

if ents:
  results = [{
    "name": ent.name,
    "counter": ent.counter
    } for ent in ents]

  # reverse list for 'descending' order
  results.sort(reverse=True)

Example result:

[{'counter': 111L, 'name': u'wasabi'}, {'counter': 51L, 'name': u'honeydew'}, {'counter': 43L, 'name': u'mars bar'}, {'counter': 37L, 'name': u'scallop'}, {'counter': 33L, 'name': u'turnip'}, {'counter': 29L, 'name': u'cornbread'}, {'counter': 16L, 'name': u'mackerel'}, {'counter': 10L, 'name': u'instant coffee'}, {'counter': 3L, 'name': u'brussel sprouts'}, {'counter': 2L, 'name': u'anchovies'}]
Kai