Решил хранить некоторые данные с временной меткой в TmmescaleDB, так как постгрес при большом количестве строк начинает ужасно тормозить.
Сделал все по доке Django и Timescale.
Вытянул образ в докере, запустил, базу создал.
Написал роутеры для баз данных, прописал данные в конфиге.
settings.py
DATABASES = {
'default': {
'ENGINE': os.environ.get('SQL_ENGINE', 'django.db.backends.postgresql'),
'NAME': os.environ.get('SQL_DATABASE', 'postgres'),
'USER': os.environ.get('SQL_USER', 'postgres'),
'PASSWORD': os.environ.get('SQL_PASSWORD', 'pass'),
'HOST': os.environ.get('SQL_HOST', '127.0.0.1'),
'PORT': os.environ.get('SQL_PORT', '5432'),
},
'data_db': {
'ENGINE': 'timescale.db.backends.postgresql',
'NAME': 'data_db',
'USER': 'postgres',
'PASSWORD': 'pass',
'HOST': '127.0.0.1',
'PORT': '5432'
}
}
DATABASE_ROUTERS = ['detector_data.dbRouter.Router', 'client.dbRouter.Router']
detector_data.dbRouter
class Router:
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read auth models go to data_db.
"""
if model._meta.app_label == 'detector_data':
return 'data_db'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write data models go to data_db.
"""
if model._meta.app_label == 'detector_data':
return 'data_db'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
return True
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'data_db'
database.
"""
if app_label == 'detector_data':
return db == 'data_db'
return None
client.dbRouter
class Router:
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read auth models go to default.
"""
if model._meta.app_label != 'detector_data':
return 'default'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write data models go to default.
"""
if model._meta.app_label != 'detector_data':
return 'default'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
return True
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'default'
database.
"""
if app_label == 'detector_data':
return db == 'default'
return None
В общем, тут все по стандарту.
Решил я уже радоваться, потому что миграции в обеих базах сработали, но тут при создании объекта класса DetectorData
from django.db import models
from django.contrib.postgres.indexes import BrinIndex
from timescale.db.models.fields import TimescaleDateTimeField
from timescale.db.models.managers import TimescaleManager
from detector.models import Detector
class DetectorData(models.Model):
detector = models.ForeignKey(
Detector,
verbose_name='Привязанный датчик',
on_delete=models.DO_NOTHING,
related_name='data'
)
first_temp = models.DecimalField('Первая температура', max_digits=4, decimal_places=2)
second_temp = models.DecimalField('Вторая температура', max_digits=4, decimal_places=2)
third_temp = models.DecimalField('Третья температура', max_digits=4, decimal_places=2)
humidity = models.DecimalField('Влажность', max_digits=4, decimal_places=2)
lightning = models.DecimalField('Освещенность', max_digits=4, decimal_places=2)
pH = models.DecimalField('Кислотность', max_digits=4, decimal_places=2)
timestamp = TimescaleDateTimeField('Время сбор данных', interval='1 day', auto_now_add=True)
objects = models.Manager()
timescale = TimescaleManager()
def __str__(self):
return f'Отчет в {self.timestamp} от {self.detector}'
class Meta:
verbose_name = 'Данные датчика'
verbose_name_plural = 'Данные датчиков'
indexes = [BrinIndex(fields=['timestamp'])]
@classmethod
def create_random(cls, detector, days=None):
data = cls.objects.create(
detector=detector,
first_temp=round(uniform(0, 20), 2),
second_temp=round(uniform(0, 20), 2),
third_temp=round(uniform(0, 20), 2),
humidity=round(uniform(0, 20), 2),
lightning=round(uniform(0, 20), 2),
pH=round(uniform(0, 20), 2),
)
if days:
data.timestamp = datetime.now().date()+timedelta(days=days)
data.save()
return data
Появилось это
Я понимаю, что тут написано, что таблица не та.
Но что с этим делать.
А еще - как все-таки сделать так, чтобы time-series модели находились в Timescale, а все остальные - в Postgres
Для справки: модель DetectorData имеет внешний ключ на Detector (они находятся в разных базах)
Буду благодарен за любую помощь!