django 如何避免使用update_or_create的IntegrityError问题?

vfhzx4xs  于 2023-04-13  发布在  Go
关注(0)|答案(1)|浏览(134)

如果有人能解释为什么我在这里抛出IntegrityError异常,以及如何避免它,我将不胜感激。
当一个对象已经存在时,update_or_create方法不是应该更新它吗?

models.py

class OHLCV(TimestampedModel):
    market = models.ForeignKey(Market, on_delete=models.CASCADE, related_name='candles', null=True)
    index = models.ForeignKey(Index, on_delete=models.CASCADE, related_name='candles', null=True)
    timeframe = models.CharField(max_length=10)
    open, high, low, close, volume = [models.FloatField(null=True) for i in range(5)]
    datetime = models.DateTimeField(null=True)

    class Meta:
        verbose_name_plural = "OHLCV"
        unique_together = [['market', 'timeframe', 'datetime'],
                           ['index', 'timeframe', 'datetime']]

任务.py

@app.task
def bulk_update_ohlcv(timeframe):
    for obj in Market.objects.filter(active=True):
        if obj.exchange.is_status_ok():
            update_ohlcv.delay('market', obj.pk, timeframe)

@app.task
def update_ohlcv(self, type, pk, timeframe):

    [code here]
    if obj.__class__ == Market:
        ohlcv, created = OHLCV.objects.update_or_create(market=obj,
                                                        timeframe=timeframe,
                                                        datetime=dt,
                                                        open=candle[1],
                                                        defaults=defaults
                                                        )

    elif obj.__class__ == Index:
        ohlcv, created = OHLCV.objects.update_or_create(index=obj,
                                                        timeframe=timeframe,
                                                        datetime=dt,
                                                        open=candle[1],
                                                        defaults=defaults
                                                        )

错误:

-celery_worker-1  | 2023-04-01T06:55:47.710298043Z IntegrityError: duplicate key value violates unique constraint 
-celery_worker-1  | 2023-04-01T06:55:47.710302260Z "market_ohlcv_market_id_timeframe_datetime_8ffd84de_uniq"
-celery_worker-1  | 2023-04-01T06:55:47.710306227Z DETAIL:  Key (market_id, timeframe, datetime)=(84, 5m, 2023-03-31 21:20:00+00) 
-celery_worker-1  | 2023-04-01T06:55:47.710310646Z already exists.
bvjveswy

bvjveswy1#

问题在于open字段位于update_or_create的kwargs中。
Django会尝试获取一个OHLCV,它匹配markettimeframedatetimeopen这四个字段。如果有一个示例匹配前三个字段,而不是open,Django会创建一个与您的约束冲突的新示例。
您需要将open字段移到默认字典中,或者将其包含在unique together约束中

相关问题