How to jsonify objects from sqlalchemy?

后端 未结 6 542
离开以前
离开以前 2021-01-21 23:15

I\'m using Flask, SQLAlchemy and javascript. I need to pass the results of my query to javascript in the json format, through AJAX, but I keep getting this error:



        
6条回答
  •  时光说笑
    2021-01-21 23:55

    Here is my solution written in python:

    step 1: custom JSON.encoder

    import json
    import uuid
    from pprint import pformat
    from datetime import datetime
    from collections import OrderedDict
    
    class CustomJSONEncoder(json.JSONEncoder):
        def default(self, obj):
            # cls = self.__class__
            if isinstance(obj, datetime):
                return obj.strftime('%Y-%m-%d %H:%M:%S.%f')
            elif isinstance(obj, uuid.UUID):
                return str(obj)
            elif hasattr(obj, '__html__'):
                return str(obj.__html__())
            elif isinstance(obj, OrderedDict):
                m = json.dumps(obj)
            elif hasattr(obj, 'to_dict'):
                return obj.to_dict()
            else:
                mp = pformat(obj, indent=2)
                print("JsonEncodeError", type(obj), mp)
                m = json.JSONEncoder.default(self, obj)
            return m
    

    step 2: override flask_app.json_encoder

    from flask import Flask
    app = Flask(__name__)
    app.json_encoder = CustomJSONEncoder
    

    step 3: Custom A Helper Class for metaclass of sqlalchemy

    class CoModel():
        """
        A `Helper Class` for `metaclass` of sqlalchemy
        usage 1 : flask_sqlalchemy
    
            from flask_sqlalchemy import SQLAlchemy
            db = SQLAlchemy(session_options=session_options)
            class TableName(db.Model, CoModel):
                pass
    
    
        usage 2: sqlalchemy
    
            from sqlalchemy.ext.declarative import declarative_base
            Base = declarative_base()
            class TableName(Base, CoModel):
                __tablename__ = 'table_name'
        """
    
        def to_dict(self):
            result = {}
            columns = self.columns()
            for col in columns:
                name = col.name
                value = getattr(self, name)
                result[name] = value
            return result
    
        @classmethod
        def columns(cls):
            tbl = getattr(cls, "__table__", None)
            if tbl is None:
                raise NameError('use sample: class TableName(db.Model, CoModel)')
            else:
                return tbl.columns
    

    Finally, if you response with flask.jsonify, it will be auto encoded by CoModel.to_dict()

    Of course, you can use json.dumps(sqlalchmey_object,cls=CustomJSONEncoder) as well.

提交回复
热议问题