将GqlQuery结果集转换为Python字典

3 投票
4 回答
3364 浏览
提问于 2025-04-11 09:26

假设我有一个这样的模型

class Foo(db.Model):
    id = db.StringProperty()
    bar = db.StringProperty()
    baz = db.StringProperty()

然后我在执行一个这样的Gql查询

foos = db.GqlQuery("SELECT * FROM Foo")

我想把这个Gql查询的结果变成一种可以在不同编程语言中操作的JSON字符串。


这是我现在的做法

  1. Foo类中添加一个方法,把它转换成字典

    def toDict(self):
        return {
             'id': self.id,
             'bar': self.bar,
             'baz': self'baz
           }
    
  2. 遍历Gql查询的结果,手动把每个Foo实例添加到字典中

    fooDict = {}
    
    for foo in foos:
        fooDict[foo.id] = foo.toDict()
    
    return simplejson.dumps(fooDict)
    

我上面的方法可以用,但感觉有点麻烦。

有没有更简洁、更“Pythonic”的处理方式呢?

最终的格式不一定要和我上面做的一模一样,只要能很好地转换成JSON,这样我就可以在Javascript/PHP等语言中使用。

4 个回答

0

http://code.google.com/p/google-app-engine-samples/source/browse/trunk/geochat/json.py?r=55

这个编码器方法可以很好地满足你把GQL转换成JSON的需求。我建议去掉一些过于复杂的日期时间选项……把时间当作纪元时间?真的有必要吗?

1

我也没办法给出太多更好的建议,不过这里有几个想法:

class Foo:
    id = db.StringProperty() # etc.
    json_attrs = 'id bar baz'.split()

# Depending on how easy it is to identify string properties, there
# might also be a way to assign json_attrs programmatically after the
# definition of Foo, like this
Foo.json_attrs = [attr for attr in dir(Foo)
                  if isStringProperty(getattr(Foo, attr))]

fooDict=dict((foo.id,dict(getattr(foo, attr)
                          for attr in Foo.json_attrs))
              for foo in foos)
2

你可以看看 google.appengine.api.datastore。这是一个比较底层的数据存储接口,google.appengine.ext.db 是在这个基础上构建的。它返回的是实体对象,这些对象是字典的子类。你可以用 GQL 来查询它,使用 google.appengine.ext.gql,或者(我个人更喜欢)使用 Query 类,这样你就不需要为 GQL 解析器构造文本字符串了。api.datastore 中的 Query 类和 这里文档中描述的 一样(但返回的是底层的实体对象,而不是模型实例)。

举个例子,你上面的查询可以改写成 "datastore.Query("Foo").all()"。

撰写回答