Package: django-timescaledb
A database backend and tooling for Timescaledb.Based ongistfrom WeRiot.Quick startInstall via pippipinstalldjango-timescaledbUse as DATABASE engine in settings.py:Standard PostgreSQLDATABASES={'default':{'ENGINE':'timescale.db.backends.postgresql',...},}PostGISDATABASES={'default':{'ENGINE':'timescale.db.backends.postgis',...},}If you already make use of a custom PostgreSQL db backend you can set
the path in settings.py.TIMESCALE_DB_BACKEND_BASE="django.contrib.gis.db.backends.postgis"Inherit from the TimescaleModel. Ahypertablewill automatically be created.classTimescaleModel(models.Model):"""
  A helper class for using Timescale within Django, has the TimescaleManager and
  TimescaleDateTimeField already present. This is an abstract class it should
  be inheritted by another class for use.
  """time=TimescaleDateTimeField(interval="1 day")objects=TimescaleManager()classMeta:abstract=TrueImplementation would look like thisfromtimescale.db.models.modelsimportTimescaleModelclassMetric(TimescaleModel):temperature=models.FloatField()If you already have a table, you can either addtimefield of typeTimescaleDateTimeFieldto your model or
rename (if not already namedtime) and change type of
existingDateTimeField(rename first then runmakemigrationsand then change the type, so thatmakemigrationsconsiders it as change in same field
instead of removing and adding new field). This also
triggers the creation of a hypertable.fromtimescale.db.models.fieldsimportTimescaleDateTimeFieldfromtimescale.db.models.managersimportTimescaleManagerclassMetric(models.Model):time=TimescaleDateTimeField(interval="1 day")objects=models.Manager()timescale=TimescaleManager()The name of the field is important as Timescale specific feratures
require this as a property of their functions. ### Reading Data“TimescaleDB hypertables are designed to behave in the same manner as
PostgreSQL database tables for reading data, using standard SQL
commands.”As such the use of the Django’s ORM is perfectally suited to this type
of data. By leveraging a custom model manager and queryset we can extend
the queryset methods to include Timescale functions.Time BucketMore InfoMetric.timescale.filter(time__range=date_range).time_bucket('time','1 hour')# expected output<TimescaleQuerySet[{'bucket':datetime.datetime(2020,12,22,11,0,tzinfo=<UTC>)},...]>Time Bucket Gap FillMore Infofrommetrics.modelsimport*fromdjango.db.modelsimportCount,Avgfromdjango.utilsimporttimezonefromdatetimeimporttimedeltaranges=(timezone.now()-timedelta(days=2),timezone.now())(Metric.timescale.filter(time__range=ranges).time_bucket_gapfill('time','1 day',ranges[0],ranges[1],datapoints=240).annotate(Avg('temperature')))# expected output<TimescaleQuerySet[{'bucket':datetime.datetime(2020,12,21,21,24,tzinfo=<UTC>),'temperature__avg':None},...]>HistogramMore Infofrommetrics.modelsimport*fromdjango.db.modelsimportCountfromdjango.utilsimporttimezonefromdatetimeimporttimedeltaranges=(timezone.now()-timedelta(days=3),timezone.now())(Metric.timescale.filter(time__range=ranges).values('device').histogram(field='temperature',min_value=50.0,max_value=55.0,num_of_buckets=10).annotate(Count('device')))# expected output<TimescaleQuerySet[{'histogram':[0,0,0,87,93,125,99,59,0,0,0,0],'device__count':463}]>