flask-marshmallow dropping the decimal point

Viewed 2072

I am using flask-marshmallow and flask-sqlalchemy, and I want to serialise a data set that contains a Numeric field, all the values have decimal places i.e. 2.5 but when marshmallow dumps it to a json it cuts off the decimal place (changes 2.5 to 2) where am I going wrong?

ma.py

from flask_marshmallow import Marshmallow

ma = Marshmallow()

app.py

import ma
import db
from flask_restful import Api
.....
api = Api(app)

api.add_resource(LookupActivities, '/lookup_activity_by_type/<string:activity_type>')

if __name__ == "__main__":
    db.init_app(app)
    ma.init_app(app)
    app.run(port=5000, debug=True)

model/lookup.py

from db import db

class LookupModel(db.Model):
    __tablename__ = "asmirt_cpd_point_lookup"
    __table_args__ = {"schema": "radcpd"}

    asmirt_activity_id = db.Column(db.Integer, primary_key=True)
    activity_type = db.Column(db.String(255))
    activity = db.Column(db.String(255))
    alt_text = db.Column(db.String(255))
    activity_points = db.Column(db.Integer)
    per_unit = db.Column(db.String(255))

    @classmethod
    def find_by_activity_type(cls, activity_type: str):
        return cls.query.filter_by(activity_type=activity_type).all()

schema/lookup.py

from ma import ma
from models.lookup import LookupModel


class LookupSchema(ma.ModelSchema):
    class Meta:
        model = LookupModel
        dump_only = ("asmirt_activity_id",)

resource/lookup.py

from flask_restful import Resource
from models.lookup import LookupModel
from schemas.lookup import LookupSchema
from flask_jwt_extended import jwt_required
from flask import jsonify

class LookupActivities(Resource):
    @classmethod
    def get(cls, activity_type):
        data = LookupModel.find_by_activity_type(activity_type=activity_type)
        print(data)
        print(data[1].activity)
        if data:
            return {"activities": lookup_schema_list.dump(data)}, 200

        return {'message', 'No activities in that group'}

For this example it will change the value 2.5 in the database but outputs 2. In other examples I will get the error message Object Decimal is not serializable. Anyone know what is causing this and how to fix it?

2 Answers

In your ma.ModelSchema class you need to override the decimal value like this:

from flask_marshmallow.fields import fields

class LookupSchema(ma.ModelSchema):
    per_unit = fields.Float()

    class Meta:
        model = LookupModel
        dump_only = ("asmirt_activity_id",)

Now you can serialize per_unit property. Repeat this for all your properties. You can use Decimal instead of Float.

Don't forget: in your db.model, per_unit has to be Float, like: per_unit = db.Column(db.Float())

Your model columns do not have decimal declaration. I guess you're trying to insert / get decimal data to / from integer declared columns. Try declaring the column as decimal.

Related