desdulianto
desdulianto

Reputation: 83

Flask-Restless dumps Decimal value from Flask-Sqlalchemy

i have this model using Flask-SQLAlchemy:

class Menu(Document, db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(80), unique=True, index=True)
    price = db.Column(db.Numeric)

and i can create api using Flask-Restless for this model. The problem is when i HTTP GET from the api url:

  File "/usr/lib/python2.6/json/encoder.py", line 344, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('10000.0000000000') is not JSON serializable

The problem is obvious the JSON encoder cannot encode Decimal value which is mapped to price (Numeric column type). Is there any workaound to enable Flask-Restless using custom JSON encoder?

Upvotes: 6

Views: 3933

Answers (2)

mickael
mickael

Reputation: 315

Here is what I did:

import simplejson as json

def postprocessor(data):
    json.dumps(data, use_decimal=True)
    return data

manager.create_api(Menu, methods=['GET', 'POST', 'PATCH'], allow_patch_many=True, postprocessors={
'PATCH_MANY': [postprocessor],
'GET_MANY': [postprocessor],
'POST': [postprocessor]
})

So the idea is to use Flask-Restless' postprocessor to encode the data with simplejson instead of json since simplejson supports the Decimal() type by specifying use_decimal=True.

Edit: Actually it seems like installing simplejson might be sufficient. No change needed in your code.

Upvotes: 5

synergetic
synergetic

Reputation: 8036

As indicated in mickael's answer, installing simpejson was sufficient. Also correct syntax for postprocessor is the following:

#first argument must be named as 'result', not 'data'
def postprocessor(result):
    json.dumps(result, use_decimal=True)
    #return data - postprocessors/preprocessors should not return values!

Upvotes: 4

Related Questions