How to serialize SqlAlchemy result to JSON?

后端 未结 27 1494
说谎
说谎 2020-11-22 09:59

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

27条回答
  •  孤街浪徒
    2020-11-22 10:09

    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 and query_class for flask_sqlalchemy db.Model class). I've updated the encoder as follows:

    app/json_encoder.py

        from sqlalchemy.ext.declarative import DeclarativeMeta
        from flask import json
    
    
        class AlchemyEncoder(json.JSONEncoder):
            def default(self, o):
                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:
                            json.dumps(value)
                            data[field] = value
                        except TypeError:
                            data[field] = None
                    return data
                return json.JSONEncoder.default(self, o)
    

    app/__init__.py

    # json encoding
    from app.json_encoder import AlchemyEncoder
    app.json_encoder = AlchemyEncoder
    

    With this I can optionally add a __json__ property that returns the list of fields I wish to encode:

    app/models.py

    class Queue(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        song_id = db.Column(db.Integer, db.ForeignKey('song.id'), unique=True, nullable=False)
        song = db.relationship('Song', lazy='joined')
        type = db.Column(db.String(20), server_default=u'audio/mpeg')
        src = db.Column(db.String(255), nullable=False)
        created_at = db.Column(db.DateTime, server_default=db.func.now())
        updated_at = db.Column(db.DateTime, server_default=db.func.now(), onupdate=db.func.now())
    
        def __init__(self, song):
            self.song = song
            self.src = song.full_path
    
        def __json__(self):
            return ['song', 'src', 'type', 'created_at']
    

    I add @jsonapi to my view, return the resultlist and then my output is as follows:

    [
    
    {
    
        "created_at": "Thu, 23 Jul 2015 11:36:53 GMT",
        "song": 
    
            {
                "full_path": "/static/music/Audioslave/Audioslave [2002]/1 Cochise.mp3",
                "id": 2,
                "path_name": "Audioslave/Audioslave [2002]/1 Cochise.mp3"
            },
        "src": "/static/music/Audioslave/Audioslave [2002]/1 Cochise.mp3",
        "type": "audio/mpeg"
    }
    
    ]
    

提交回复
热议问题