python - Avoiding cartesian product with Django -


i have following 3 tables defined.

class operator(models.model):     displayname = models.charfield(max_length=64)      class meta:         app_label = "experiment"         db_table = "experiment_operator"  class operatorsummary(models.model):     operator = models.foreignkey(operator, related_name="transactionsummary")     transactioncount = models.integerfield()     transactionvalue = models.decimalfield(max_digits=18, decimal_places=2)     starttime = models.datetimefield(default=timezone.now())      class meta:         app_label = "experiment"         db_table = "experiment_operatorsummary"  class operatoralerts(models.model):     operator = models.foreignkey(operator, related_name="alertsummary")     alertscore = models.integerfield()     alertcount = models.integerfield()     starttime = models.datetimefield(default=timezone.now())      class meta:         app_label = "experiment"         db_table = "experiment_operatoralerts" 

for operator, retrieve alertscore , transactioncount given date range. query i'm using looks this:

tz = timezone.get_default_timezone()     vs = operator.objects.filter(displayname="jimmy",                              transactionsummary__starttime__gte=tz.localize(datetime(year=2013, month=10, day=1)),                              alertsummary__starttime__gte=tz.localize(datetime(year=2013, month=10, day=1)))\     .annotate(totaltransactions=sum("transactionsummary__transactioncount"),               totalalerts=sum("alertsummary__alertscore"))\     .values("displayname", "transactionsummary__transactioncount", "alertsummary__alertscore") 

this query performs cartesian product , returns rows in operatoralerts , operatorsummary table match query. returns:

{'alertsummary__alertscore': 20, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 10} {'alertsummary__alertscore': 44, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 10} {'alertsummary__alertscore': 543, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 10} {'alertsummary__alertscore': 20, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 22} {'alertsummary__alertscore': 44, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 22} {'alertsummary__alertscore': 543, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 22} {'alertsummary__alertscore': 20, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 234} {'alertsummary__alertscore': 44, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 234} {'alertsummary__alertscore': 543, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 234} 

i'd fix following result:

{'alertsummary__alertscore': 607, 'displayname': u'jimmy', 'transactionsummary__transactioncount': 266} 

all results collapsed 1 row alertscore , transactioncount summed.

is possible? can fall making separate query operatoralerts , operatorsummary , iterating on result set in python results want or calling .aggregate, i'm sure there must better way?

try reversing order in apply values() , annotate() methods. values() should come first:

vs = operator.objects.filter(displayname="jimmy",                              transactionsummary__starttime__gte=tz.localize(datetime(year=2013, month=10, day=1)),                              alertsummary__starttime__gte=tz.localize(datetime(year=2013, month=10, day=1)))\     .values("displayname")\     .annotate(totaltransactions=sum("transactionsummary__transactioncount"),               totalalerts=sum("alertsummary__alertscore")) 

this group results fields mentioned in values() , generate annotation each group. order significant - as documented.

applying values() , annotate() in way (i.e. annotate() before values()) generate annotations every item separately.

please note code above group results displayname. may want group different field, example pk.

also, assume in real code want values multiple operators @ once. if queried 1 operator @ time (like in example) better of using aggregate() instead of annotate().


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -