Domanda

Lettura: http://code.google.com/appengine /docs/python/datastore/gqlreference.html

Voglio usare:

: = IN

ma non sono sicuro di come farlo funzionare. Supponiamo che

class User(db.Model):
    name = db.StringProperty()

class UniqueListOfSavedItems(db.Model):
    str = db.StringPropery()
    datesaved = db.DateTimeProperty()

class UserListOfSavedItems(db.Model):
    name = db.ReferenceProperty(User, collection='user')
    str = db.ReferenceProperty(UniqueListOfSavedItems, collection='itemlist')

Come posso fare una query che mi dia l'elenco degli elementi salvati per un utente? Ovviamente posso fare:

q = db.Gql("SELECT * FROM UserListOfSavedItems WHERE name :=", user[0].name)

ma questo mi dà un elenco di chiavi. Voglio ora prendere quell'elenco e inserirlo in una query per estrarre il campo str da UniqueListOfSavedItems. Pensavo di poter fare:

q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems WHERE := str in q")

ma qualcosa non va ... qualche idea? È (sono al mio lavoro quotidiano, quindi non posso provarlo ora):

q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems __key__ := str in q)

nota a margine: che problema diabolicamente difficile da cercare perché tutto quello che mi interessa davvero è il " IN " operatore.

È stato utile?

Soluzione

Dato che hai un elenco di chiavi, non è necessario eseguire una seconda query, puoi invece eseguire un recupero batch. Prova questo:

#and this should get me the items that a user saved
useritems = db.get(saveditemkeys)

(Nota che non è nemmeno necessaria la clausola di guardia - un db.get su 0 entità è cortocircuitato in modo appropriato.)

Qual è la differenza, potresti chiedere? Bene, un db.get richiede circa 20-40ms. Una query, d'altra parte (GQL o no) richiede circa 160-200ms. Ma aspetta, peggiora! L'operatore IN è implementato in Python e si traduce in più query, che vengono eseguite in serie. Quindi, se si esegue una query con un filtro IN per 10 chiavi, si eseguono 10 operazioni di query separate da 160 ms, per un totale di circa 1,6 secondi di latenza. Un singolo db.get, al contrario, avrà lo stesso effetto e prenderà un totale di circa 30ms.

Altri suggerimenti

+1 a Adam per avermi portato sulla strada giusta. Sulla base del suo puntatore e facendo qualche ricerca su Ricerca codice, ho la seguente soluzione.

usersaveditems = User.Gql(“Select * from UserListOfSavedItems where user =:1”, userkey)

saveditemkeys = []

for item in usersaveditems:
    #this should create a list of keys (references) to the saved item table
    saveditemkeys.append(item.str())    

if len(usersavedsearches > 0):
    #and this should get me the items that a user saved
    useritems = db.Gql(“SELECT * FROM UniqueListOfSavedItems WHERE __key__ in :1’, saveditemkeys)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top