Превращение набора результатов GqlQuery в словарь Python - PullRequest
3 голосов
/ 17 октября 2008

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

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)
    

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

Есть ли более чистый, более "питонский" способ справиться с этим?

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

Ответы [ 4 ]

2 голосов
/ 17 октября 2008

Взгляните на 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 ()".

1 голос
/ 17 октября 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)
0 голосов
/ 03 ноября 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 и т. Д. ... тоже.

0 голосов
/ 18 октября 2008

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

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

...