1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.db.models.functions.mixins import (
FixDurationInputMixin,
NumericOutputFieldMixin,
)
from django.utils import timezone
from datetime import timedelta
from timescale.db.models.fields import TimescaleDateTimeField
class Interval(models.Func):
"""
A helper class to format the interval used by the time_bucket_gapfill function to generate correct timestamps.
Accepts an interval e.g '1 day', '5 days', '1 hour'
"""
function = "INTERVAL"
template = "%(function)s %(expressions)s"
def __init__(self, interval, *args, **kwargs):
if not isinstance(interval, models.Value):
interval = models.Value(interval)
super().__init__(interval, *args, **kwargs)
class TimeBucket(models.Func):
"""
Implementation of the time_bucket function from Timescale.
Read more about it here - https://docs.timescale.com/latest/using-timescaledb/reading-data#time-bucket
Response:
[
{'bucket': '2020-12-22T10:00:00+00:00', 'devices': 12},
{'bucket': '2020-12-22T09:00:00+00:00', 'devices': 12},
{'bucket': '2020-12-22T08:00:00+00:00', 'devices': 12},
{'bucket': '2020-12-22T07:00:00+00:00', 'devices': 12},
]
"""
function = "time_bucket"
name = "time_bucket"
def __init__(self, expression, interval, *args, **kwargs):
if not isinstance(interval, models.Value):
interval = models.Value(interval)
output_field = TimescaleDateTimeField(interval=interval)
super().__init__(interval, expression, output_field=output_field)
class TimeBucketNG(models.Func):
"""
Implementation of the time_bucket_ng function from Timescale.
Read more about it here - https://docs.timescale.com/api/latest/hyperfunctions/time_bucket_ng/#timescaledb-experimental-time-bucket-ng
Response:
[
{'bucket': '2020-12-01T00:00:00+00:00', 'devices': 12},
{'bucket': '2020-11-01T00:00:00+00:00', 'devices': 12},
{'bucket': '2020-10-01T00:00:00+00:00', 'devices': 12},
{'bucket': '2020-09-01T00:00:00+00:00', 'devices': 12},
]
"""
function = "timescaledb_experimental.time_bucket_ng"
name = "timescaledb_experimental.time_bucket_ng"
def __init__(self, expression, interval, *args, **kwargs):
if not isinstance(interval, models.Value):
interval = models.Value(interval)
output_field = TimescaleDateTimeField(interval=interval)
super().__init__(interval, expression, output_field=output_field)
class TimeBucketGapFill(models.Func):
"""
IMplementation of the time_bucket_gapfill function from Timescale
Read more about it here - https://docs.timescale.com/latest/using-timescaledb/reading-data#gap-filling
Response:
[
...
{'bucket': '2020-12-22T11:36:00+00:00', 'temperature__avg': 52.7127405105567},
{'bucket': '2020-12-22T11:42:00+00:00', 'temperature__avg': None},
...
]
"""
function = "time_bucket_gapfill"
name = "time_bucket_gapfill"
def __init__(
self, expression, interval, start, end, datapoints=None, *args, **kwargs
):
if not isinstance(interval, models.Value):
interval = Interval(interval)
if datapoints:
interval = interval / datapoints
output_field = TimescaleDateTimeField(interval=interval)
super().__init__(interval, expression, start, end, output_field=output_field)
|