【问题标题】:Python query objects are not serializablePython 查询对象不可序列化
【发布时间】:2013-04-27 09:46:06
【问题描述】:

当我尝试对查询对象进行编码时,出现以下错误:

  File "C:\Program File\Python27\lib\json\encoder.py", line 264, in iterencode
        return _iterencode(o, 0)
      File "C:\Program File\Python27\lib\json\encoder.py", line 178, in default
        raise TypeError(repr(o) + " is not JSON serializable")
    TypeError: ActivitySummaries(key=Key('ActivitySummaries', 634), activated_users=0, broker_approved=0, broker_registered=0, broker_searched=1, closed_deals=0, company_registered=0, company_searched=4, deal_appoved=0, investor_approved=0, investor_registered=0, investor_searched=3, registered_users=0, timestamp=datetime.datetime(2013, 4, 8, 20, 41, 47, 574000), watchlisting=0) is not JSON serializable

jquery:

$.ajax({
        data: someData,
        url: someUrl,
        type: 'POST',
        dataType: 'json',
        success: function(data)
        {
            alert("Success");
        },
        error : function(request, status, thrownError){
            alert("Error");
            return;
                }
    });

处理程序:

 search_pattern = roledb.ActivitySummaries.searchPatterns(start_date, end_date)

            self.response.write(json.dumps(search_pattern))

roledb.py

class ActivitySummaries(ndb.Model):    
    def searchPatterns(cls, start_date, end_date):
            activities = cls.query()
            results = []
            for activity in activities:
                if ( activity.timestamp >= start_date and activity.timestamp <= end_date ):
                    results.append(activity)

            return results

我是 Google App Engine 的新手,我不知道为什么它不能使用 JSON 进行序列化。

我们将衷心感谢您的任何意见。

【问题讨论】:

    标签: python json google-app-engine serialization jinja2


    【解决方案1】:

    您只能在 Python 中序列化“简单”数据类型,如字典、数组等。因此,您不应该序列化查询对象,而是该查询的结果——我猜它会是一个数组。

    另一个解决方案是继承JSONEncoder 来处理任意值,就像我为 DateTime 所做的 sn-p:

    import datetime
    from json import JSONEncoder
    
    class DateEncoder(JSONEncoder):
        def default(self, obj):
            if isinstance(obj, datetime.date):
                return obj.isoformat()
            return JSONEncoder.default(self, obj)
    

    并使用它指定cls=DateEncoder:

    json.dumps(data, cls=DateEncoder)
    

    【讨论】:

      【解决方案2】:

      您几乎可以将任何您想要的 JSON 序列化为 JSON,但除了简单的结构之外,您还需要自己完成所有操作。并编写您自己的取消选择器。

      但是,在您的情况下,我怀疑序列化 Query 对象是否有意义。你会在另一端用它做什么? Javascript 不能用它做任何事情,如果您只想传递查询参数,那么只需传递这些参数而不是 Query 对象。

      也许您实际上想从查询中序列化结果集并将其传递回客户端。在这种情况下,请执行 fetch,或使用游标来检索结果块。

      ndb.Model 基类有一个 to_dict() 方法,这是您通常调用的方法,然后您将序列化字典。

      result = json.dumps([dumps(i.to_dict()) for i in query.fetch(100)) 
      

      或者更好的使用map查询的方法(甚至还有map_async)

      def dump(obj):
          return json.dumps(obj.to_dict())
      
      result = query.map(dump)
      

      https://developers.google.com/appengine/docs/python/ndb/queries#map

      您需要将此与其他答案结合起来,为日期和任何其他非简单数据类型提供自定义编码器。

      【讨论】:

      • 你能举个例子说明如何使用 to_dict() 方法吗?
      【解决方案3】:

      我发现以下解决方案适用于序列化包含 ndb.DateTimeProperty 作为子级的 ndb.Model 对象。

      from datetime import datetime
      import json
      from google.appengine.ext import ndb
      
      __author__ = 'achuinard'
      
      class GaeEncoder(json.JSONEncoder):
          def default(self, obj):
              if isinstance(obj, datetime):
                  return int(obj.strftime('%s'))
              elif isinstance(obj, ndb.Model):
                  return obj.to_dict()
              else:
                  return json.JSONEncoder.default(self, obj)
      
      def serialize(object_to_serialize):
          return json.dumps(object_to_serialize, cls=GaeEncoder)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-11
        • 2010-11-30
        • 2017-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多