Превращение набора результатов GqlQuery в словарь Python
-
03-07-2019 - |
Вопрос
Допустим, у меня есть такая модель
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 и т. д. ... тоже.