【问题标题】:Turning a GqlQuery result set into a python dictionary将 GqlQuery 结果集转换为 python 字典
【发布时间】:2010-09-17 17:57:25
【问题描述】:

假设我有一个这样的模型

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

我要像这样进行 GqlQuery

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

我想将 GqlQuery 的结果转换成某种 JSON 字符串,我可以使用不同的语言对其进行操作。


这就是我现在的做法

  1. Foo 类添加一个将其转换为字典的方法

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

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

我上面的方法有效,但感觉有点恶心。

有没有更简洁、更“Pythonic”的方式来处理这个问题?

结束格式不必完全是我上面所做的。它必须是可以很好地转换为 JSON 的东西,这样我就可以从 Javascript/PHP/whatever 处理它。

【问题讨论】:

  • 我希望我在一个类似的问题上回答得很好 - see here

标签: python google-app-engine gqlquery


【解决方案1】:

看看google.appengine.api.datastore。它是 google.appengine.ext.db 构建的较低级别的数据存储 API,它返回 Entity 对象,它是 dict 的子类。您可以使用带有google.appengine.ext.gql 的 GQL 来查询它,或者(我个人的偏好)使用 Query 类,这样就无需为 GQL 解析器构建文本字符串来解析。 api.datastore 中的 Query 类的行为与 documented here 完全相同(但返回较低级别的 Entity 对象而不是 Model 实例)。

例如,您的上述查询可以重新表述为“datastore.Query("Foo").all()”。

【讨论】:

    【解决方案2】:

    我不能做得比这更好,但这里有几个想法:

    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)
    

    【讨论】:

    • 这很有趣。我不知道 dir() 是这样做的。
    【解决方案3】:

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

    编码器方法将很好地解决您的 GQL-to-JSON 需求。我建议摆脱一些过多的日期时间选项......作为一个时代的超时时间?真的吗?

    【讨论】:

      【解决方案4】:

      您可以在 GAE 上使用 web2py 并执行以下操作:

      db.define_table('foo',SQLField('bar'),SQLField('baz'))
      rows=db(db.foo.id>0).select()
      ### rows is a list, rows.response is a list of tuples
      for row in rows: print  dict(row)
      

      也可以在 Oracle、Postgresql、Mssql、mysql 等上运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-25
        • 1970-01-01
        • 2010-10-31
        • 2011-06-20
        • 1970-01-01
        相关资源
        最近更新 更多