3 回答

TA貢獻1801條經驗 獲得超16個贊
我發現的一種解決方案是在模型保存調用周圍使用 try/ except 塊。嘗試添加傳感器讀數,大多數情況下都會成功,但如果發生碰撞,請處理該錯誤。確保拋出的異常正是由于該沖突而引起的,然后將時間戳增加一微秒(最小分辨率)。然后重復嘗試保存傳感器讀數。由于首先發生的碰撞概率較低,因此這幾乎總是會成功。下面是經過測試的代碼,用于遞歸地處理遞增時間戳直到成功。
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)
更穩健的實現還可能在中止之前添加最大嘗試次數。

TA貢獻1810條經驗 獲得超4個贊
一般來說,我建議至少在某種程度上從 Django 中獲取該傳感器表的表管理,使用 psycopg2 或其他驅動程序進行插入,并在 上創建適當的主鍵,然后公開該表(或Sensor, time
在它)作為一個 Django 模型,它可以從中讀取,如果需要的話,也許可以使用連接。這些應該寫入一次,因此您不必處理更新,這通常就是它需要非復合主鍵的原因。在某些時候 Django 應該真正開始支持復合主鍵,但遺憾的是他們沒有。
其他方法可能有效,但它們可能根本無法很好地擴展。因此,如果您關心攝取率,我可能會嘗試不同的方法。
添加回答
舉報