Python查询对象不可序列化

时间:2013-05-03 03:48:42

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

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

  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进行序列化。

任何投入都将非常感激。

3 个答案:

答案 0 :(得分:7)

你只能在Python中序列化“简单”的数据类型,比如词典,数组等。所以你应该序列化查询对象,但这个查询的结果 - 我想它将是一个数组。

另一种解决方案是将JSONEncoder子类化为处理任意值,就像我为DateTime所做的那样:

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)

答案 1 :(得分:2)

你可以将你想要的任何东西序列化为JSON,但除了简单的结构之外,你需要自己完成所有这些。并写下你自己的不合格。

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

也许您确实希望从查询中序列化结果集并将其传递回客户端。在这种情况下,请进行提取,或使用光标检索结果块。

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

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

答案 2 :(得分:1)

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

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)