Trasformare un set di risultati GqlQuery in un dizionario Python
-
03-07-2019 - |
Domanda
Diciamo che ho un modello come questo
class Foo(db.Model):
id = db.StringProperty()
bar = db.StringProperty()
baz = db.StringProperty()
E vado a GqlQuery come questo
foos = db.GqlQuery("SELECT * FROM Foo")
Voglio prendere i risultati di GqlQuery e trasformarli in una sorta di stringa JSON che posso manipolare da lingue diverse.
Ecco come lo sto facendo ora
-
Aggiungi un metodo alla classe Foo che lo converte in un dizionario
def toDict(self): return { 'id': self.id, 'bar': self.bar, 'baz': self'baz }
-
Scorri i risultati di GqlQuery e aggiungi manualmente ogni istanza di Foo a un dizionario
fooDict = {} for foo in foos: fooDict[foo.id] = foo.toDict() return simplejson.dumps(fooDict)
Il mio approccio sopra funziona ma sembra un po 'grossolano.
Esiste un più pulito, più "Pythonic" modo di gestire questo?
Il formato finale non deve essere esattamente quello che ho fatto sopra. Deve solo essere qualcosa che si converta bene in JSON in modo che io possa gestirlo da Javascript / PHP / qualunque cosa.
Soluzione
Dai un'occhiata a google .appengine.api.datastore . È l'API di archivio dati di livello inferiore su cui si basa google.appengine.ext.db e restituisce oggetti Entity, che eseguono la sottoclasse di dict. Puoi interrogarlo usando GQL con google.appengine.ext.gql o (la mia preferenza personale) usa la classe Query, che evita la necessità di costruire stringhe di testo per l'analisi del parser GQL. La classe Query in api.datastore si comporta esattamente come quella documentata qui (ma restituisce gli oggetti Entity di livello inferiore anziché le istanze del modello).
Ad esempio, la query sopra può essere riformulata come " datastore.Query (" Foo "). all () " ;.
Altri suggerimenti
Non posso fare di meglio, ma ecco un paio di idee:
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
Il metodo encoder risolverà bene le tue esigenze da GQL a JSON. Consiglierei di eliminare alcune delle eccessive opzioni di datetime .... fuori tempo come un'epoca? davvero?
Puoi usare web2py su GAE e fare:
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)
Funziona anche su Oracle, Postgresql, Mssql, mysql, ecc ...