使用Python将Google App Engine Datastore查询转换为JSON

2 投票
3 回答
5309 浏览
提问于 2025-04-16 14:08

我该如何在Python中从Google App Engine的Datastore获取一个JSON对象呢?

我在Datastore中有一个模型,里面有以下字段:

id
key_name
object
userid
created

现在我想获取某个用户的所有对象:

query = Model.all().filter('userid', user.user_id())

我该如何从这个查询中创建一个JSON对象,以便我可以写入呢?

我想通过AJAX调用来获取这些数据。

3 个回答

0

我做了以下操作,把谷歌查询对象转换成了json格式。我使用了上面提到的jql_json_parser的逻辑,除了把所有内容转换成unicode的那部分。我想保留数据类型,比如整数、浮点数和空值。

import json
class JSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if hasattr(obj, 'isoformat'): #handles both date and datetime objects
            return obj.isoformat()
        else:
            return json.JSONEncoder.default(self, obj)

class BaseResource(webapp2.RequestHandler):
    def to_json(self, gql_object):
        result = []
        for item in gql_object:
            result.append(dict([(p, getattr(item, p)) for p in item.properties()]))
        return json.dumps(result, cls=JSONEncoder)

现在你可以继承BaseResource类,并在gql_object上调用self.to_json。

1

如果我理解得没错,你实现了一个类似这样的系统。听起来你想把一个任意的JSON对象存储到GAE的数据存储模型中。为了做到这一点,你需要在把数据存入数据库时,将JSON编码成某种字符串,而在取出数据时,再把字符串解码成Python的数据结构。你需要使用一个JSON编码/解码工具来完成这个过程。我想GAE的基础设施里应该有这样的工具。例如,你可以使用一个“包装类”来处理编码和解码。大概是这样的……

class InnerClass(db.Model):
    jsonText = db.TextProperty()
    def parse(self):
        return OuterClass(self)

class Wrapper:
    def __init__(self, storage=None):
        self.storage = storage
        self.json = None
        if storage is not None:
            self.json = fromJsonString(storage.jsonText)
    def put(self):
        jsonText  = ToJsonString(self.json)
        if self.storage is None:
            self.storage = InnerClass()
        self.storage.jsonText = jsonText
        self.storage.put()

然后总是对解析后的包装对象进行操作,而不是直接操作内部类。

def getall():
    all = db.GqlQuery("SELECT * FROM InnerClass")
    for x in all:
        yield x.parse()

(未经测试)。你可以查看datastoreview.py,里面有一些类似的模型实现。

8

不确定你是否得到了想要的答案,但你是想问如何将查询对象中的模型(条目)数据直接解析成一个JSON对象吗?(至少这是我一直在寻找的东西)。

我写了这个代码来将查询对象中的条目解析成一系列的JSON对象:

def gql_json_parser(query_obj):
    result = []
    for entry in query_obj:
        result.append(dict([(p, unicode(getattr(entry, p))) for p in entry.properties()]))
    return result

你可以让你的应用程序通过简单的JSON编码来响应AJAX请求,例如:

query_data = MyModel.all()
json_query_data = gql_json_parser(query_data)
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(simplejson.dumps(json_query_data))

你的应用程序将返回类似这样的内容:

[{'property1': 'value1', 'property2': 'value2'}, ...]

如果这对你有帮助,请告诉我!

撰写回答