Django has some good automatic serialization of ORM models returned from DB to JSON format.
How to serialize SQLAlchemy query result to JSON format?
I tried jsonpickle.encode
but it encodes query object itself.
I tried json.dumps(items)
but it returns
TypeError: <Product('3', 'some name', 'some desc')> is not JSON serializable
Is it really so hard to serialize SQLAlchemy ORM objects to JSON /XML? Isn't there any default serializer for it? It's very common task to serialize ORM query results nowadays.
What I need is just to return JSON or XML data representation of SQLAlchemy query result.
SQLAlchemy objects query result in JSON/XML format is needed to be used in javascript datagird (JQGrid http://www.trirand.com/blog/)
You can just use
.json
on the SqlAlchemy ResultFlask-JsonTools package has an implementation of JsonSerializableBase Base class for your models.
Usage:
Now the
User
model is magically serializable.If your framework is not Flask, you can just grab the code
Use the built-in serializer in SQLAlchemy:
If you're transferring the object between sessions, remember to detach the object from the current session using
session.expunge(obj)
. To attach it again, just dosession.add(obj)
.Under Flask, this works and handles datatime fields, transforming a field of type
'time': datetime.datetime(2018, 3, 22, 15, 40)
into"time": "2018-03-22 15:40:00"
:For security reasons you should never return all the model's fields. I prefer to selectively choose them.
Flask's json encoding now supports UUID, datetime and relationships (and added
query
andquery_class
for flask_sqlalchemydb.Model
class). I've updated the encoder as follows:With this I can optionally add a
__json__
property that returns the list of fields I wish to encode:I add @jsonapi to my view, return the resultlist and then my output is as follows:
A flat implementation
You could use something like this:
and then convert to JSON using:
It will ignore fields that are not encodable (set them to 'None').
It doesn't auto-expand relations (since this could lead to self-references, and loop forever).
A recursive, non-circular implementation
If, however, you'd rather loop forever, you could use:
And then encode objects using:
This would encode all children, and all their children, and all their children... Potentially encode your entire database, basically. When it reaches something its encoded before, it will encode it as 'None'.
A recursive, possibly-circular, selective implementation
Another alternative, probably better, is to be able to specify the fields you want to expand:
You can now call it with:
To only expand SQLAlchemy fields called 'parents', for example.