Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 358
desdulianto Avatar asked Feb 21 '13 06:02

desdulianto


2 Answers

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.

like image 86
mickael Avatar answered Sep 18 '22 10:09

mickael


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!
like image 42
synergetic Avatar answered Sep 18 '22 10:09

synergetic