1

クエリ オブジェクトをエンコードしようとすると、次のエラーが発生します。

  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 を使用してシリアル化できない理由がわかりません。

ご意見をお待ちしております。

4

3 に答える 3

7

Python では、辞書や配列などの「単純な」データ型のみをシリアル化できます。したがって、クエリ オブジェクトではなく、このクエリの結果をシリアル化する必要があります。配列になると思います。

もう 1 つの解決策は、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)
于 2013-05-03T04:29:02.407 に答える
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を参照してください

これを他の回答と組み合わせて、日付やその他の非単純なデータ型のカスタム エンコーダーを提供する必要があります。

于 2013-05-03T07:27:13.227 に答える