2

TypeError: Object of type Decimal is not JSON serializable


While I am running in postman api i get the above error because sales_qty is decimal , I dont know how to parse decimal in a for loop and return it as json

from flask import Flask, jsonify

import decimal,json

result= [('V_M_001', 'KITE', 'Napkin', 1, 2, 12, 0, Decimal('0'), Decimal('0'), Decimal('0'), Decimal('0')), 
        ('V_M_001', 'KITE', 'Napkin', 2, 4, 34, 5, Decimal('1'), Decimal('4'), Decimal('0'), Decimal('0'))]
        
def fun():

   for i in result:
        data_all.append({
                            "machine_name":i.machine_name,
                            "location":i.location, 
                            "item_name":i.item_name,
                            "row_no":i.row_no,
                            "require_minimum_stk_qty":i.require_minimum_stk_qty,
                            "capacity":i.capacity,
                            "stock_qty":i.stock_qty,
                            "sales_qty":i.sales_qty,
                            "available_qty":i.available_qty,
                            "sales_day_qty":i.sales_day_qty,
                            "sales_week_qty":i.sales_week_qty
        
        })
        
    return jsonify(data_all)

fun()

Output: TypeError: Object of type Decimal is not JSON serializable

Cadoiz
  • 1,446
  • 21
  • 31
pythoncoder
  • 575
  • 3
  • 8
  • 17
  • Does this answer your question? [Python JSON serialize a Decimal object](https://stackoverflow.com/questions/1960516/python-json-serialize-a-decimal-object) – Maurice Meyer Dec 15 '20 at 16:06
  • no could you suggest different solution – pythoncoder Dec 16 '20 at 03:49
  • There are two JSON numeric types, `int` and `float`. No complex, no `Decimal`. So if you want to use JSON to represent your data you have little choice but to decide which of the two available types you want. Or, if preserving the precision of `decimal.Decimal` is important, you can pass the data as a string and leave the conversion up to the receiving process. – BoarGules Dec 16 '20 at 08:04

3 Answers3

6

Use json.dump with cls argument, I believe that when ever the json module dont know how to convert, it will call the default function.

import json
import decimal

class Encoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal): return float(obj)

json.dumps( ... , cls = Encoder)

```python
Trung Đức
  • 61
  • 1
  • 3
3
import decimal

from flask import current_app as app
from flask import Jsonify
from flask.json import JSONEncoder

class JsonEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            return float(obj)
        return JSONEncoder.default(self, obj)

@app.route('/test_jsonify')
def test_jsonify():
    data = {
        'float': 7.5,
        'decimal': decimal.Decimal(7.5)
    }

    app.json_encoder = JsonEncoder
    return jsonify(data)

(found here Flask Jsonify Custom JsonEncoder | Lua Software Code)

SergeyS
  • 59
  • 3
  • Please add further details to expand on your answer, such as working code or documentation citations. – Community Sep 06 '21 at 12:52
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Thibaud Sep 06 '21 at 14:53
  • It’s a totally work code with the Flask. For more experience you can use link. – SergeyS Sep 07 '21 at 13:22
0

You can use the json.dumps() with default encoder str().

json.dumps( dict_obj_with_decimal , default = str)
OHM
  • 318
  • 2
  • 6
  • this is a quick solution if you don't bother about the data *type* but most of the time, json as data exchange require and/or preserve data type. – Jasonw Aug 01 '23 at 08:26