Django models 异常:保存Django数据模型时引发decimal.InvalidOperation

Django models 异常:保存Django数据模型时引发decimal.InvalidOperation,django-models,python-3.6,Django Models,Python 3.6,我正在将加密货币数据存储到Django数据模型中(使用Postgres数据库)。绝大多数记录都已成功保存。但是,特别是在一条记录上,我得到了一个异常decimal.invalidooperation 奇怪的是,我看不出问题记录中保存的值与其他成功保存的值有什么不同。我已经包括了一个完整的堆栈跟踪。在保存数据之前,我已经将原始值输出到调试日志。下面是我将数据保存到的数据模型。以及将数据保存到数据模型的代码 我被难住了!有人知道问题出在哪里吗 数据模型 class OHLCV(m.Model):

我正在将加密货币数据存储到Django数据模型中(使用Postgres数据库)。绝大多数记录都已成功保存。但是,特别是在一条记录上,我得到了一个异常
decimal.invalidooperation

奇怪的是,我看不出问题记录中保存的值与其他成功保存的值有什么不同。我已经包括了一个完整的堆栈跟踪。在保存数据之前,我已经将原始值输出到调试日志。下面是我将数据保存到的数据模型。以及将数据保存到数据模型的代码

我被难住了!有人知道问题出在哪里吗

数据模型

class OHLCV(m.Model):
    """ Candles-stick data (open, high, low, close, volume) """

    # class variables
    _field_names = None
    timeframes = ['1m', '1h', '1d']

    # database fields
    timestamp = m.DateTimeField(default=timezone.now)
    market = m.ForeignKey('bc.Market', on_delete=m.SET_NULL, null=True, related_query_name='ohlcv_markets', related_name='ohlcv_market')
    timeframe = m.DurationField() # 1 minute, 5 minute, 1 hour, 1 day, or the like
    open = m.DecimalField(max_digits=20, decimal_places=10)
    high = m.DecimalField(max_digits=20, decimal_places=10)
    low = m.DecimalField(max_digits=20, decimal_places=10)
    close = m.DecimalField(max_digits=20, decimal_places=10)
    volume = m.DecimalField(max_digits=20, decimal_places=10)
@classmethod
def fetch_ohlcv(cls, market:Market, timeframe:str, since=None, limit=None):
    """
    Fetch OHLCV data and store it in the database

    :param market:
    :type market: bc.models.Market
    :param timeframe: '1m', '5m', '1h', '1d', or the like
    :type timeframe: str
    :param since:
    :type since: datetime
    :param limit:
    :type limit: int
    """

    global log
    if since:
        since = since.timestamp()*1000

    exchange = cls.get_exchange()
    data = exchange.fetch_ohlcv(market.symbol, timeframe, since, limit)
    timeframe = cls.parse_timeframe_string(timeframe)
    for d in data:
        try:
            timestamp = datetime.fromtimestamp(d[0] / 1000, tz=timezone.utc)
            log.debug(f'timestamp={timestamp}, market={market}, timeframe={timeframe}, open={d[1]}, high={d[2]}, low={d[3]}, close={d[4]}, volume={d[5]}')
            cls.objects.create(
                timestamp=timestamp,
                market=market,
                timeframe=timeframe,
                open=d[1],
                high=d[2],
                low=d[3],
                close=d[4],
                volume=d[5],
            )
        except IntegrityError:
            pass
        except decimal.InvalidOperation as e:
            error_log_stack(e)
保存数据模型的代码

class OHLCV(m.Model):
    """ Candles-stick data (open, high, low, close, volume) """

    # class variables
    _field_names = None
    timeframes = ['1m', '1h', '1d']

    # database fields
    timestamp = m.DateTimeField(default=timezone.now)
    market = m.ForeignKey('bc.Market', on_delete=m.SET_NULL, null=True, related_query_name='ohlcv_markets', related_name='ohlcv_market')
    timeframe = m.DurationField() # 1 minute, 5 minute, 1 hour, 1 day, or the like
    open = m.DecimalField(max_digits=20, decimal_places=10)
    high = m.DecimalField(max_digits=20, decimal_places=10)
    low = m.DecimalField(max_digits=20, decimal_places=10)
    close = m.DecimalField(max_digits=20, decimal_places=10)
    volume = m.DecimalField(max_digits=20, decimal_places=10)
@classmethod
def fetch_ohlcv(cls, market:Market, timeframe:str, since=None, limit=None):
    """
    Fetch OHLCV data and store it in the database

    :param market:
    :type market: bc.models.Market
    :param timeframe: '1m', '5m', '1h', '1d', or the like
    :type timeframe: str
    :param since:
    :type since: datetime
    :param limit:
    :type limit: int
    """

    global log
    if since:
        since = since.timestamp()*1000

    exchange = cls.get_exchange()
    data = exchange.fetch_ohlcv(market.symbol, timeframe, since, limit)
    timeframe = cls.parse_timeframe_string(timeframe)
    for d in data:
        try:
            timestamp = datetime.fromtimestamp(d[0] / 1000, tz=timezone.utc)
            log.debug(f'timestamp={timestamp}, market={market}, timeframe={timeframe}, open={d[1]}, high={d[2]}, low={d[3]}, close={d[4]}, volume={d[5]}')
            cls.objects.create(
                timestamp=timestamp,
                market=market,
                timeframe=timeframe,
                open=d[1],
                high=d[2],
                low=d[3],
                close=d[4],
                volume=d[5],
            )
        except IntegrityError:
            pass
        except decimal.InvalidOperation as e:
            error_log_stack(e)

查看您的数据并检查其是否符合字段限制:

  • 必须符合max_数字
  • 小数点应小于小数点
  • 并根据:整位数不应大于最大位数-小数位数 不确定fetch_ohlcv函数如何填充数据数组,但如果有除法,十进制数字的数量可能大于10。 我遇到的问题是,整数部分的位数太多,因此无法满足最后一个要求


    查看有关类似问题的更多信息。

    MikeyE,您找到解决方案了吗?我也面临着一个完全相同的例外。我就像你说的那样执行除法。修好了,谢谢!