3 回答
TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個贊
為了使用 timescale db,我創(chuàng)建了一個虛擬主鍵字段,它會欺騙 Django 并將復(fù)合鍵值表示為單個 json 元組。
TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個贊
我發(fā)現(xiàn)的一種解決方案是在模型保存調(diào)用周圍使用 try/ except 塊。嘗試添加傳感器讀數(shù),大多數(shù)情況下都會成功,但如果發(fā)生碰撞,請?zhí)幚碓撳e誤。確保拋出的異常正是由于該沖突而引起的,然后將時間戳增加一微秒(最小分辨率)。然后重復(fù)嘗試保存?zhèn)鞲衅髯x數(shù)。由于首先發(fā)生的碰撞概率較低,因此這幾乎總是會成功。下面是經(jīng)過測試的代碼,用于遞歸地處理遞增時間戳直到成功。
class SensorReading(models.Model):
time = models.DateTimeField(primary_key=True, default=datetime.now)
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
value = models.FloatField()
def save(self, *args, **kwargs):
self.save_increment_time_on_duplicate(*args, **kwargs)
def save_increment_time_on_duplicate(self, *args, **kwargs):
try:
super().save(*args, **kwargs)
except IntegrityError as exception:
if all (k in exception.args[0] for k in ("Key","time", "already exists")):
self.time = str(parse_datetime(self.time) + timedelta(microseconds=1))
self.save_increment_time_on_duplicate(*args, **kwargs)
更穩(wěn)健的實(shí)現(xiàn)還可能在中止之前添加最大嘗試次數(shù)。
TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個贊
一般來說,我建議至少在某種程度上從 Django 中獲取該傳感器表的表管理,使用 psycopg2 或其他驅(qū)動程序進(jìn)行插入,并在 上創(chuàng)建適當(dāng)?shù)闹麈I,然后公開該表(或Sensor, time在它)作為一個 Django 模型,它可以從中讀取,如果需要的話,也許可以使用連接。這些應(yīng)該寫入一次,因此您不必處理更新,這通常就是它需要非復(fù)合主鍵的原因。在某些時候 Django 應(yīng)該真正開始支持復(fù)合主鍵,但遺憾的是他們沒有。
其他方法可能有效,但它們可能根本無法很好地擴(kuò)展。因此,如果您關(guān)心攝取率,我可能會嘗試不同的方法。
添加回答
舉報
