jsonify a SQLAlchemy result set in Flask [duplicate] jsonify a SQLAlchemy result set in Flask [duplicate] flask flask

jsonify a SQLAlchemy result set in Flask [duplicate]


It seems that you actually haven't executed your query. Try following:

return jsonify(json_list = qryresult.all())

[Edit]: Problem with jsonify is, that usually the objects cannot be jsonified automatically. Even Python's datetime fails ;)

What I have done in the past, is adding an extra property (like serialize) to classes that need to be serialized.

def dump_datetime(value):    """Deserialize datetime object into string form for JSON processing."""    if value is None:        return None    return [value.strftime("%Y-%m-%d"), value.strftime("%H:%M:%S")]class Foo(db.Model):    # ... SQLAlchemy defs here..    def __init__(self, ...):       # self.foo = ...       pass    @property    def serialize(self):       """Return object data in easily serializable format"""       return {           'id'         : self.id,           'modified_at': dump_datetime(self.modified_at),           # This is an example how to deal with Many2Many relations           'many2many'  : self.serialize_many2many       }    @property    def serialize_many2many(self):       """       Return object's relations in easily serializable format.       NB! Calls many2many's serialize property.       """       return [ item.serialize for item in self.many2many]

And now for views I can just do:

return jsonify(json_list=[i.serialize for i in qryresult.all()])

Hope this helps ;)

[Edit 2019]:In case you have more complex objects or circular references, use a library like marshmallow).


Here's what's usually sufficient for me:

I create a serialization mixin which I use with my models. The serialization function basically fetches whatever attributes the SQLAlchemy inspector exposes and puts it in a dict.

from sqlalchemy.inspection import inspectclass Serializer(object):    def serialize(self):        return {c: getattr(self, c) for c in inspect(self).attrs.keys()}    @staticmethod    def serialize_list(l):        return [m.serialize() for m in l]

All that's needed now is to extend the SQLAlchemy model with the Serializer mixin class.

If there are fields you do not wish to expose, or that need special formatting, simply override the serialize() function in the model subclass.

class User(db.Model, Serializer):    id = db.Column(db.Integer, primary_key=True)    username = db.Column(db.String)    password = db.Column(db.String)    # ...    def serialize(self):        d = Serializer.serialize(self)        del d['password']        return d

In your controllers, all you have to do is to call the serialize() function (or serialize_list(l) if the query results in a list) on the results:

def get_user(id):    user = User.query.get(id)    return json.dumps(user.serialize())def get_users():    users = User.query.all()    return json.dumps(User.serialize_list(users))


I had the same need, to serialize into json. Take a look at this question. It shows how to discover columns programmatically. So, from that I created the code below. It works for me, and I'll be using it in my web app. Happy coding!

def to_json(inst, cls):    """    Jsonify the sql alchemy query result.    """    convert = dict()    # add your coversions for things like datetime's     # and what-not that aren't serializable.    d = dict()    for c in cls.__table__.columns:        v = getattr(inst, c.name)        if c.type in convert.keys() and v is not None:            try:                d[c.name] = convert[c.type](v)            except:                d[c.name] = "Error:  Failed to covert using ", str(convert[c.type])        elif v is None:            d[c.name] = str()        else:            d[c.name] = v    return json.dumps(d)class Person(base):    __tablename__ = 'person'    id = Column(Integer, Sequence('person_id_seq'), primary_key=True)    first_name = Column(Text)    last_name = Column(Text)    email = Column(Text)    @property    def json(self):        return to_json(self, self.__class__)