Превращение набора результатов GqlQuery в словарь Python

Допустим, у меня есть такая модель

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 или откуда угодно.


person Mark Biek    schedule 17.10.2008    source источник
comment
Надеюсь, я хорошо ответил на аналогичный вопрос - смотрите здесь.   -  person Jim McNeill    schedule 30.04.2011


Ответы (4)


Взгляните на google.appengine. api.datastore. Это API-интерфейс хранилища данных более низкого уровня, на котором строится google.appengine.ext.db, и он возвращает объекты Entity, которые являются подклассами dict. Вы можете запросить его с помощью GQL с google.appengine.ext.gql или (мое личное предпочтение) использовать класс Query, который избавляет вас от необходимости создавать текстовые строки для синтаксического анализа GQL. Класс Query в api.datastore ведет себя точно так же, как тот, который задокументирован здесь. (но возвращает объекты Entity более низкого уровня вместо экземпляров Model).

Например, приведенный выше запрос можно переформулировать как "datastore.Query("Foo").all()".

person Nick Johnson    schedule 17.10.2008

Я не могу сделать намного лучше, чем это, но вот пара идей:

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)
person Alex Coventry    schedule 17.10.2008
comment
Это интересно. Я не знал, что dir() сделал это. - person Mark Biek; 17.10.2008

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

Метод кодировщика прекрасно решит ваши потребности в преобразовании GQL в JSON. Я бы порекомендовал избавиться от некоторых чрезмерных параметров даты и времени .... вне времени как эпохи? В самом деле?

person jamtoday    schedule 18.10.2008

Вы можете использовать web2py в GAE и делать:

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 и т. д.

person massimo    schedule 03.11.2008