File: expressions.py

package info (click to toggle)
python-django-timescaledb 0.2.13-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 304 kB
  • sloc: python: 512; sh: 20; makefile: 6; sql: 4
file content (108 lines) | stat: -rw-r--r-- 3,567 bytes parent folder | download
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)