2008-10-17 5 views
3

Скажем, у меня есть модель, как этотПревращение GqlQuery результирующего набора в словарь питона

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/что угодно.

+0

Надеюсь, я ответил на этот вопрос по аналогичному вопросу - [см. Здесь] (http://stackoverflow.com/questions/2114659/how-to-serialize-db-model-objects-to-json/5788453# 5788453). – jaffamcneill 2011-04-30 18:41:23

ответ

2

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

В качестве примера приведенный выше запрос можно переформулировать как «datastore.Query (« Foo »). All()».

1

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

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

Это интересно. Я не знал, что это сделал. – 2008-10-17 14:23:32

0

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

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

+0

Фактически это означало метод encode(). – jamtoday 2008-10-18 08:42:20

-1

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

Смежные вопросы