Ligando um conjunto de resultados para um dicionário GqlQuery pitão
-
03-07-2019 - |
Pergunta
Vamos dizer que tenho um modelo como este
class Foo(db.Model):
id = db.StringProperty()
bar = db.StringProperty()
baz = db.StringProperty()
E eu vou a GqlQuery como este
foos = db.GqlQuery("SELECT * FROM Foo")
Quero levar os resultados da GqlQuery e se transformar em algum tipo de string JSON que eu possa manipular a partir de diferentes idiomas.
Aqui está como eu estou fazendo isso agora
-
Adicionar um método para o Foo classe que converte em um dicionário
def toDict(self): return { 'id': self.id, 'bar': self.bar, 'baz': self'baz }
-
loop através dos resultados GqlQuery e adicionar manualmente cada instância Foo a um dicionário
fooDict = {} for foo in foos: fooDict[foo.id] = foo.toDict() return simplejson.dumps(fooDict)
A minha abordagem acima obras, mas ele se sente meio nojento.
Existe uma mais limpa, mais maneira "Pythonic" para lidar com isso?
O formato final não tem que ser exatamente o que eu fiz acima. Ele só tem que ser algo que converte bem para JSON para que eu possa lidar com isso de Javascript / PHP / whatever.
Solução
Dê uma olhada google .appengine.api.datastore . É o menor nível API de armazenamento de dados que google.appengine.ext.db baseia-se, e ele retorna objetos de entidade, que subclasse dict. Você pode consultá-lo usando GQL com google.appengine.ext.gql , ou (minha preferência pessoal) usar a classe Query, o que evita a necessidade de você para construir cadeias de texto para o analisador GQL para análise. A classe Query no comporta api.datastore exatamente como o que documentado aqui (mas retorna o nível mais baixo Entidade objetos em vez de instâncias do modelo).
Como exemplo, a sua consulta acima pode ser reformulado como "datastore.Query (" Foo "). Tudo ()".
Outras dicas
Eu não posso fazer muito melhor do que isso, mas aqui estão algumas idéias:
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
O método codificador vai resolver o seu GQL-to-JSON necessidades bem. Eu recomendo se livrar de algumas das opções de data e hora excessivas .... o tempo como uma época? realmente?
Você pode usar web2py no GAE e fazer:
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)
Funciona em Oracle, PostgreSQL, MSSQL, MySQL, etc ... também.