Created
August 31, 2013 16:07
-
-
Save sloat/6399164 to your computer and use it in GitHub Desktop.
JSON encoder for SQLAlchemy models, using the inspection API. Not thoroughly tested. No warranty, blah blah. Improvements welcomed!
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
import json | |
from sqlalchemy.inspection import inspect | |
class AlchemyEncoder(json.JSONEncoder): | |
'''JSON encoder for SQLAlchemy models, using inspection API''' | |
def __init__(self, skipkeys=False, ensure_ascii=True, | |
check_circular=True, allow_nan=True, sort_keys=False, | |
indent=None, separators=None, default=None, relations=False, | |
**kw): | |
self._include_relations = relations | |
super(AlchemyEncoder, self).__init__( | |
skipkeys=False, | |
ensure_ascii=True, | |
check_circular=True, | |
allow_nan=True, | |
indent=None, | |
separators=None, | |
default=None, | |
**kw | |
) | |
def default(self, obj): | |
''' | |
inspect columns of sqlalchemy model, create secondary encoder if | |
necessary for relationships and make it so we don't go more than one | |
level deep. | |
''' | |
info = inspect(obj) | |
if not info.is_instance: | |
raise TypeError('%s is not an instance' % obj) | |
output = {} | |
cols = info.mapper.columns | |
for colname in cols.keys(): | |
if colname in info.dict: | |
output[colname] = info.dict[colname] | |
else: | |
output[colname] = None | |
if self._include_relations: | |
encoder = AlchemyEncoder(relations=False) | |
for relname, relinfo in info.mapper.relationships.items(): | |
if relname in info.dict: | |
if relinfo.uselist: | |
output[relname] = [] | |
for relobj in info.dict[relname]: | |
if relobj == obj: | |
output[relname].append({'self': True}) | |
else: | |
output[relname].append(encoder.default(relobj)) | |
else: | |
output[relname] = encoder.default(relobj) | |
return output | |
def model_json(obj, relations=False): | |
return json.dumps(obj, cls=AlchemyEncoder, relations=relations) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment