Question

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

Je veux utiliser:

: = IN

mais je ne sais pas comment le faire fonctionner. Supposons ce qui suit

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')

Comment puis-je faire une requête qui me donne la liste des éléments enregistrés pour un utilisateur? Évidemment je peux faire:

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

mais cela me donne une liste de clés. Je veux maintenant prendre cette liste et la placer dans une requête pour extraire le champ str de UniqueListOfSavedItems. Je pensais pouvoir faire:

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

mais quelque chose ne va pas ... des idées? Est-ce (je suis à mon travail, alors je ne peux pas le tester maintenant):

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

note latérale: quel problème diablement difficile à rechercher parce que tout ce qui me préoccupe, c’est le & IN; IN " opérateur.

Était-ce utile?

La solution

Étant donné que vous avez une liste de clés, vous n'avez pas besoin de faire une seconde requête. Vous pouvez effectuer une récupération par lot. Essayez ceci:

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

(Notez que vous n'avez même pas besoin de la clause guard: un db.get sur 0 entités est court-circuité.)

Quelle est la différence, vous pouvez demander? Eh bien, un disque prend environ 20 à 40 ms. Une requête, par contre (GQL ou non) prend environ 160-200ms. Mais attends, ça devient pire! L'opérateur IN est implémenté en Python et se traduit en plusieurs requêtes exécutées en série. Ainsi, si vous effectuez une requête avec un filtre IN pour 10 clés, vous effectuez 10 opérations de requête distinctes de 160 ms, pour un total d'environ 1,6 secondes de latence. Une seule base de données, au contraire, aura le même effet et durera environ 30 ms.

Autres conseils

+1 à Adam pour m'avoir mis sur la bonne voie. En me basant sur son pointeur et en effectuant des recherches dans Code Search, j’ai la solution suivante.

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top