Pregunta

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

Quiero usar:

: = IN

pero no estoy seguro de cómo hacerlo funcionar. Asumamos lo siguiente

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

¿Cómo puedo hacer una consulta que me permita obtener la lista de elementos guardados para un usuario? Obviamente puedo hacer:

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

pero eso me da una lista de claves. Ahora quiero tomar esa lista y ponerla en una consulta para sacar el campo str de UniqueListOfSavedItems. Pensé que podía hacer:

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

pero algo no está bien ... ¿alguna idea? Es (estoy en mi trabajo diario, así que no puedo probar esto ahora):

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

nota al margen: qué problema tan endiabladamente difícil de buscar porque lo único que realmente me importa es el "IN" operador.

¿Fue útil?

Solución

Ya que tiene una lista de claves, no necesita hacer una segunda consulta; en su lugar, puede hacer una búsqueda por lotes. Prueba esto:

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

(Tenga en cuenta que ni siquiera necesita la cláusula de protección: un db.get en 0 entidades está cortocircuitado adecuadamente).

¿Cuál es la diferencia, puede preguntar? Bueno, un db.get tarda unos 20-40ms. Una consulta, por otro lado (GQL o no) toma alrededor de 160-200ms. ¡Pero espera, se pone peor! El operador IN se implementa en Python y se traduce en múltiples consultas, que se ejecutan en serie. Entonces, si realiza una consulta con un filtro IN para 10 teclas, está realizando 10 operaciones de consulta independientes de 160 ms, para un total de aproximadamente 1,6 segundos de latencia. Un solo db.get, por el contrario, tendrá el mismo efecto y tomará un total de aproximadamente 30 ms.

Otros consejos

+1 a Adam por ayudarme en el camino correcto. Basado en su puntero, y haciendo algunas búsquedas en Code Search, tengo la siguiente solución.

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top