【问题标题】:Serializing Python Arrow objects for the Flask-Restless API为 Flask-Restless API 序列化 Python 箭头对象
【发布时间】:2015-03-02 13:43:11
【问题描述】:

我目前正在使用 Flask-Restless 开发一个应用程序。当我用相应的 arrow 字段替换我的 SQLAlchemy 模型的典型 DateTime 字段时,一切都很顺利。这是由于 SQLAlchemy-Utils 及其ArrowType 字段的帮助。

但是,在使用 API 返回这些对象的 JSON 表示后,我收到以下错误:

TypeError:Arrow [2015-01-05T01:17:48.074707] 不是 JSON 可序列化的

哪里是修改模型序列化方式的理想位置?我是要修改 Flask-Restless 代码以支持 Arrow 对象,还是编写一个 Flask-Restless 可以识别并用于检索 JSON 兼容对象的模型方法?

与此同时,我还可以编写一个丑陋的后处理器函数,但该解决方案似乎是一个糟糕的 hack。

以下是带有 ArrowType 字段的示例模型:

class Novel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Unicode, unique=True, nullable=False)
    created_at = db.Column(ArrowType, nullable=False)

    def __init__(self, title):
        self.title = title
        self.created_at = arrow.utcnow()

【问题讨论】:

    标签: python json serialization flask-restless


    【解决方案1】:

    Arrow 现在有一个for_json 方法。例如:arrow.utcnow().for_json()

    【讨论】:

      【解决方案2】:

      支持箭头类型的自定义JSONEncoder 怎么样?查看 Flask-Restless 源代码,它在底层使用了 Flask 内置的 jsonify。有关以不同格式序列化常规 datetime 对象的示例,请参阅此 sn-p:http://flask.pocoo.org/snippets/119/

      这是一个完整的独立示例,可以很好地衡量:

      import flask
      import flask.ext.sqlalchemy
      import flask.ext.restless
      from flask.json import JSONEncoder
      import sqlalchemy_utils
      import arrow
      
      app = flask.Flask(__name__)
      app.config['DEBUG'] = True
      app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
      db = flask.ext.sqlalchemy.SQLAlchemy(app)
      
      class Event(db.Model):
          id = db.Column(db.Integer, primary_key=True)
          timestamp = db.Column(sqlalchemy_utils.ArrowType)
      
      class ArrowJSONEncoder(JSONEncoder):
          def default(self, obj):
              try:
                  if isinstance(obj, arrow.Arrow):
                      return obj.format('YYYY-MM-DD HH:mm:ss ZZ')
                  iterable = iter(obj)
              except TypeError:
                  pass
              else:
                  return list(iterable)
              return JSONEncoder.default(self, obj)
      
      app.json_encoder = ArrowJSONEncoder
      
      db.create_all()
      manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
      manager.create_api(Event, methods=['GET','POST'])
      
      app.run()
      

      从您帖子中的两个选项中,我建议将该方法添加到您的模型类中以检索与 JSON 兼容的对象,只是因为它更简单且更易于维护。如果你想修改 Flask-Restless,你需要 fork 或者猴子补丁。

      【讨论】:

        猜你喜欢
        • 2015-09-09
        • 2016-01-14
        • 2016-11-14
        • 2014-12-29
        • 2016-01-16
        • 2015-03-11
        • 2013-10-16
        • 2021-10-17
        • 2017-09-03
        相关资源
        最近更新 更多