[Python][Django] query voor dag/maand opbrengst

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • MaartenBW
  • Registratie: Mei 2015
  • Laatst online: 02-10 12:42
Beste tweakers graag hulp bij het volgende probleem:

Mijn vraag
Ik heb een eigen PV-logger gemaakt. Hierbij log ik de opbrengsten van de omvormer elke 10min.
In de data zitten de volgende velden:

Timestamp
Huidige wattage (w)
totale opbrengst (kwh) (sinds installatie PV pannelen.)

Het totale opbrengst veld is dus een steeds oplopende waarde.

Nu wil ik graag een grafiek maken waar ik de dag opbrengsten van bepaalde dagen of maanden in weergeef. Dus bijv van een grafiek van een maand met alle dag opbrengsten en van een jaar met alle maand opbrengsten.

Als ik van een bepaalde dag de opbrengst wil weten, moet ik dus de laatste entry van de vorige dag aftrekken van de laatste entry van die betreffende dag.

Als ik dat voor een maand wil, moet ik dit dus 30 keer doen. Ik heb dit nu gebeund met een for loops, maar dit blijkt erg langzaam te zijn.

Mijn vraag is dus of er een query te bedenken is waarmee ik dit beter/ sneller kan doen?
Een paar pointers waar ik op moet googlen (django/sql termen) zou al erg helpen.Ik zit nu een beetje vast en kom niet verder.

Relevante software en hardware die ik gebruik:
Django 1.11.x
Python 3.7
...

Wat ik al gevonden of geprobeerd heb
mijn huidige oplossing is als volgt:

Python:
1
2
3
4
5
6
7
8
9
10
11
data = []
if dateS.month == datetime.now().month:
    einddag = datetime.now().day
else:
    einddag = monthrange(dateS.year, dateS.month)[1]
for day in range(1,einddag+1):
    date =  datetime(dateS.year,dateS.month,day)
    date2= date + relativedelta(days=-1)
    diff = noneToFloat(Inverter_log.objects.filter(timestamp__day=day,timestamp__month=dateS.month,timestamp__year=dateS.year).aggregate(Max('totaal'))['totaal__max'])-noneToFloat(Inverter_log.objects.filter(timestamp__day=date2.day,timestamp__month=date2.month,timestamp__year=date2.year).aggregate(Max('totaal'))['totaal__max'])
    data.append(diff)     
return JsonResponse(data, safe=False)


dateS is hier de selected datum.

het model is: Inverter_log, met de velden 'Totaal' en 'Timestamp'

Alle reacties


Acties:
  • 0 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 02-10 08:45
Wat voor database gebruik je? Dit in code oplossen gaat gegarandeerd niet performen idd. Met een goeie query kom je een heel eind, zeker als je een time-series database gebruikt.

Heb zelf ook in Grafana een PV dashboard gemaakt wat met MySQL praat (slechte keus, I know, maar het werkt) en soortgelijke queries doet.

Acties:
  • 0 Henk 'm!

  • Elfjes
  • Registratie: Januari 2007
  • Niet online
Kun je niet al bij het loggen van de data, de opbrengst sinds het vorige tijdstip (en de tijd sinds de vorige tijdstip) uitrekenen? Dan worden je queries wellicht een stuk makkelijker.

Bla bla bla...


Acties:
  • 0 Henk 'm!

  • MaartenBW
  • Registratie: Mei 2015
  • Laatst online: 02-10 12:42
Bedankt voor jullie reacties.
Het is inmiddels gelukt!!

Waar ik blijkbaar naar opzoek was is de volgende query in SQL:

SQL:
1
2
3
4
SELECT MAX(totaal), dag
FROM inverter_log
WHERE [alle data binnen een maand]
GROUP BY [dag]


Nu moest ik alleen nog uitvinden hoe dit in de Django ORM moest:

Python:
1
Inverter_log.objects.filter(timestamp__year=dateS.year, timestamp__month=dateS.month).annotate(date=Trunc('timestamp', 'day', output_field=DateField())).values('date').annotate(max=Max('totaal'), day = ExtractDay('date')).values_list('day','max')


Dit resulteerd in een lijst met alle eind totalen binnen een dag per dag. Deze kan ik vervolgens makkelijk van elkaar aftrekken om de opbrengst per dag te krijgen. (y)

Het loopt nu vele malen sneller dan dan mijn eerste implementatie 8)

Acties:
  • 0 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 02-10 08:45
Dit zijn van die momenten dat je beter even géén ORM/querybuilder kunt gebruiken. Wordt het alleen maar lastiger van.