6

Im wondering, how can i get a SUM of a rating entity i get from the datastore (python)?

should i:

ratingsum = 0
for rating in ratings:
    ratingsum + rating

print ratingsum

?

David Underhill
  • 15,896
  • 7
  • 53
  • 61
Alon
  • 63
  • 1
  • 3

2 Answers2

12

Yep, that's pretty much it. Retrieve all the entities you want to sum, and sum them in your app. There is no SUM in GQL.

If what you're trying to accomplish is to find the average rating for an entity, there's a better way.

class RateableThing(db.Model):
    num_ratings = db.IntegerProperty()
    avg_rating = db.FloatProperty()

Finding the thing's average rating is a simple lookup, and adding a new rating is just:

thing.avg_ratings = ((thing.avg_ratings * thing.num_ratings) + new_rating) / thing.num_ratings + 1
thing.num_ratings += 1
thing.put()

The prevailing idiom of the App Engine datastore is to do as much work as you can on write, and as little as possible on read, since reads will happen much more often.

Jason Hall
  • 20,632
  • 4
  • 50
  • 57
  • ho you mean in each write to calculate the rating and write it on each write and not calculate on read? does calling the thing.num_ratings gets the whole sum of the entities? or should i just up the numbers on each write? because i moved to datastore todo duplications and save keys for each rating so i could know who rated what and so on. i dont want a sum entity that keeps updating. is that what you mean? – Alon Apr 21 '10 at 23:56
  • `num_ratings` is the number of times the thing has been rated. So each time you add a rating, increment `num_ratings` -- if you want to keep track of who's rated, you can keep a `ListProperty` of users. If you want to keep track of who's rated, *and what they rated*, a `ListProperty` of `Rating` (user and score) objects. But still keep the simple rating (num_ and avg_) to avoid calculating on each read of the thing's rating. Only when you want to inspect the full rating data should you go into the list of user ratings. – Jason Hall Apr 22 '10 at 00:10
  • so i should always keep a summary table for rating where i up the rating on each rating of user for the calculation. thanks alot :) – Alon Apr 22 '10 at 00:20
  • You can't have ListProperties of composite, user-defined data types, unfortunately. – Nick Johnson Apr 22 '10 at 10:53
0

I can't answer the Google App Engine part of your question, but your code (if you change the + to a +=) is equivalent to:

ratingsum = sum(ratings)

I'm pretty sure you can use sum() on any sequence or iterable containing number-like objects.

Ben Hoyt
  • 10,694
  • 5
  • 60
  • 84
  • to your answer, i cant. its a float. 4.5. i cant sum it up and add it up. its not iterable :( – Alon Apr 21 '10 at 23:53