Last active
November 20, 2018 12:36
-
-
Save kodekracker/b44dea8df6c0c90fdcdb to your computer and use it in GitHub Desktop.
A Custom SqlAlchemy JSON encoder class to encode models instances in json format which supports major object instances useful in developing api's in flask.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To use this custom JsonEncoder class, you have to create a __json__() named | |
# function in each sqlalchemy model class, which basically return a list of model | |
# class attributes to be parsed, otherwise all attributes are processed present | |
# in `dir(class_name)`. | |
# | |
# Model Example: | |
# class User(db.Model): | |
# id = db.Column(db.Integer, primary_key=True) | |
# name = db.Column(db.String(100)) | |
# email = db.Column(db.String(100)) | |
# | |
# def __init__(self, name, email): | |
# self.name = name | |
# self.email = email | |
# | |
# def __json__(self): | |
# return ['name', 'email'] | |
# | |
# | |
# And, also add this custom json encoder class (i.e AlchemyJsonEncoder) in your | |
# flask application instance (i.e app) | |
# | |
# app = Flask(__name__) | |
# app.json_encoder = AlchemyJSONEncoder | |
# | |
# Note:: This json encoder class supports various objects | |
# 1) Datetime | |
# 2) UUID | |
# 3) date | |
# 4) Decimal (returned by SqlAlchemy db.Numeric class) | |
# 5) Markup | |
# | |
from sqlalchemy.ext.declarative import DeclarativeMeta | |
from flask import json | |
from decimal import Decimal | |
from datetime import date | |
class AlchemyJSONEncoder(json.JSONEncoder): | |
def default(self, o): | |
# check if object `o` is of custom declared model instance | |
if isinstance(o.__class__, DeclarativeMeta): | |
data = {} | |
fields = o.__json__() if hasattr(o, '__json__') else dir(o) | |
for field in [f for f in fields if not f.startswith('_') and | |
f not in ['metadata', 'query', 'query_class']]: | |
value = o.__getattribute__(field) | |
try: | |
if json.dumps(value): | |
data[field] = value | |
except TypeError: | |
data[field] = None | |
return data | |
# check if object `o` is of Decimal instance | |
elif isinstance(o, Decimal): | |
return o.to_eng_string() | |
# check if object `o` is of date instance | |
elif isinstance(o, date): | |
return o.isoformat() | |
# rest of objects are handled by default JSONEncoder like 'Datetime', | |
# 'UUID', 'Markdown' and various others | |
return json.JSONEncoder.default(self, o) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment