File "/usr/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python3.7/site-packages/werkzeug/middleware/dispatcher.py", line 66, in __call__
return app(environ, start_response)
File "/usr/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/usr/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/lib/python3.7/site-packages/flask_rest_jsonapi/decorators.py", line 47, in wrapper
return func(*args, **kwargs)
File "/usr/lib/python3.7/site-packages/flask/views.py", line 89, in view
return self.dispatch_request(*args, **kwargs)
File "/usr/lib/python3.7/site-packages/flask_rest_jsonapi/decorators.py", line 83, in wrapper
raise e
File "/usr/lib/python3.7/site-packages/flask_rest_jsonapi/decorators.py", line 76, in wrapper
return func(*args, **kwargs)
File "/usr/lib/python3.7/site-packages/flask_rest_jsonapi/resource.py", line 81, in dispatch_request
return make_response(json.dumps(response, cls=JSONEncoder), 200, headers)
File "/usr/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python3.7/site-packages/flask_rest_jsonapi/utils.py", line 26, in default
return json.JSONEncoder.default(self, obj)
File "/usr/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type _AssociationDict is not JSON serializable
The sqlalchemy proxy object is implemented using the _AssociationDict class which the JSON encoder does not know how to serialize. The marshmallow schema for the object is defined as
class ResourceSchema(Schema):
id = fields.Integer(as_string=True, dump_only=True)
title = fields.Str()
url = fields.Str()
language = fields.Str()
tags = fields.Dict(keys=fields.Str(), values=fields.Str())
I didn't see a way to pass in a specialized JSON encoder to solve this. So I changed utils.py as follows (for reference see the flask-restless implementation)
import json
from uuid import UUID
from datetime import datetime
from sqlalchemy.ext.associationproxy import _AssociationDict
from sqlalchemy.ext.associationproxy import _AssociationList
from sqlalchemy.ext.associationproxy import _AssociationSet
class JSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
# Attributes values that come from association proxy
# collections need to be cast to plain old Python data types
# so that the JSON serializer can handle them.
if isinstance(obj, _AssociationList):
return list(obj)
if isinstance(obj, _AssociationSet):
return set(obj)
if isinstance(obj, _AssociationDict):
return dict(obj)
if isinstance(obj, UUID):
return str(obj)
return json.JSONEncoder.default(self, obj)
Alternatively, allowing the user to pass a class for the JSON encoder would also work.
Hi --
My model uses a sqlalchemy dictionary based collection proxy. When serializing a model instance I get the following exception
The sqlalchemy proxy object is implemented using the
_AssociationDict
class which the JSON encoder does not know how to serialize. The marshmallow schema for the object is defined asI didn't see a way to pass in a specialized JSON encoder to solve this. So I changed
utils.py
as follows (for reference see the flask-restless implementation)Alternatively, allowing the user to pass a class for the JSON encoder would also work.