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

StackOverflow https://stackoverflow.com/questions/212125

Вопрос

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

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

И я собираюсь GqlQuery, как это

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

Я хочу взять результаты GqlQuery и превратить его в некую строку JSON, которой я могу манипулировать на разных языках.

<Ч>

Вот как я это делаю сейчас

<Ол>
  • Добавьте метод в класс Foo , который преобразует его в словарь

    def toDict(self):
        return {
             'id': self.id,
             'bar': self.bar,
             'baz': self'baz
           }
    
  • Циклически просматривайте результаты GqlQuery и вручную добавляйте каждый экземпляр Foo в словарь

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

    Мой подход, описанный выше, работает, но он кажется грубым.

    Есть ли чище, больше "Pythonic"? способ справиться с этим?

    Конечный формат не обязательно должен быть таким, как я делал выше. Просто это должно быть что-то, что хорошо конвертируется в JSON, чтобы я мог справиться с этим из Javascript / PHP / что угодно.

    Это было полезно?

    Решение

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

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

    Другие советы

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

    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)
    

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

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

    Вы можете использовать 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 и т. д. ... тоже.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top