3 回答

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
為了使用 timescale db,我創(chuàng)建了一個(gè)虛擬主鍵字段,它會(huì)欺騙 Django 并將復(fù)合鍵值表示為單個(gè) json 元組。

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊
我發(fā)現(xiàn)的一種解決方案是在模型保存調(diào)用周圍使用 try/ except 塊。嘗試添加傳感器讀數(shù),大多數(shù)情況下都會(huì)成功,但如果發(fā)生碰撞,請(qǐng)?zhí)幚碓撳e(cuò)誤。確保拋出的異常正是由于該沖突而引起的,然后將時(shí)間戳增加一微秒(最小分辨率)。然后重復(fù)嘗試保存?zhèn)鞲衅髯x數(shù)。由于首先發(fā)生的碰撞概率較低,因此這幾乎總是會(huì)成功。下面是經(jīng)過測(cè)試的代碼,用于遞歸地處理遞增時(shí)間戳直到成功。
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個(gè)贊
一般來(lái)說,我建議至少在某種程度上從 Django 中獲取該傳感器表的表管理,使用 psycopg2 或其他驅(qū)動(dòng)程序進(jìn)行插入,并在 上創(chuàng)建適當(dāng)?shù)闹麈I,然后公開該表(或Sensor, time
在它)作為一個(gè) Django 模型,它可以從中讀取,如果需要的話,也許可以使用連接。這些應(yīng)該寫入一次,因此您不必處理更新,這通常就是它需要非復(fù)合主鍵的原因。在某些時(shí)候 Django 應(yīng)該真正開始支持復(fù)合主鍵,但遺憾的是他們沒有。
其他方法可能有效,但它們可能根本無(wú)法很好地?cái)U(kuò)展。因此,如果您關(guān)心攝取率,我可能會(huì)嘗試不同的方法。
添加回答
舉報(bào)