La clase Query

Nota: Se recomienda encarecidamente a los desarrolladores que creen aplicaciones nuevas que usen la biblioteca de cliente de NDB, que ofrece varias ventajas en comparación con esta biblioteca de cliente, como el almacenamiento automático en caché de entidades mediante la API Memcache. Si actualmente usas la biblioteca de cliente de DB anterior, consulta la guía de migración de DB a NDB.

La clase Query representa una consulta para obtener entidades de App Engine Datastore. (Consulta también la clase relacionada GqlQuery, que define consultas mediante GQL, un lenguaje de consulta similar a SQL).

Query se define en el módulo google.appengine.ext.db.

Nota: El mecanismo de consulta basado en índices admite una amplia gama de consultas y es adecuado para la mayoría de las aplicaciones. Sin embargo, no admite algunos tipos de consultas habituales en otras tecnologías de bases de datos. En concreto, las combinaciones y las consultas de agregación no se admiten en el motor de consultas de Datastore. Consulta la página Consultas de Datastore para ver las limitaciones de las consultas de Datastore.

Introducción

Una aplicación crea un objeto de consulta para un tipo de entidad determinado llamando al constructor Query directamente

class Song(db.Model):
  title = db.StringProperty()
  composer = db.StringProperty()
  date = db.DateTimeProperty()

q = db.Query(Song)

o el método de clase all() de la clase de modelo del tipo:

q = Song.all()

Si no se modifica más, la instancia resultante de class Query recuperará todas las entidades del tipo especificado. Después, se pueden usar llamadas de método en el objeto para personalizar la consulta con criterios de filtro adicionales, condiciones de ancestro y órdenes de clasificación:

q.filter('title =', 'Imagine')
q.ancestor(ancestor_key)
q.order('-date')

Para mayor comodidad, todos estos métodos devuelven el propio objeto de consulta para que se puedan concatenar en una sola instrucción:

q.filter('title =', 'Imagine').ancestor(key).order('-date')

La aplicación puede ejecutar la consulta y acceder a los resultados de cualquiera de las siguientes formas:

  • Trata el objeto de consulta como un objeto iterable para procesar las entidades coincidentes de una en una:

    for song in q:
      print song.title

    De esta forma, se llama implícitamente al método run() de la consulta para generar las entidades coincidentes. Por lo tanto, es equivalente a

    for song in q.run():
      print song.title

    Puedes definir un límite en el número de resultados que se procesarán con el argumento de palabra clave limit:

    for song in q.run(limit=5):
      print song.title

    La interfaz del iterador no almacena en caché los resultados, por lo que, al crear un nuevo iterador a partir del objeto de consulta, se vuelve a iterar la misma consulta desde el principio.

  • Llama al método get() de la consulta para obtener la primera entidad coincidente que se encuentre en Datastore:

    song = q.get()
    print song.title
  • Llama al método de la consulta fetch() para obtener una lista de todas las entidades coincidentes hasta un número de resultados especificado:

    results = q.fetch(limit=5)
    for song in results:
      print song.title

    Al igual que con run(), el objeto de consulta no almacena en caché los resultados, por lo que, si se llama a fetch() una segunda vez, se vuelve a emitir la misma consulta.

    Nota: Rara vez tendrás que usar este método. Casi siempre es mejor usar run() en su lugar.

Constructor

El constructor de la clase Query se define de la siguiente manera:

clase Consulta (model_class=None, keys_only=False, cursor=None, namespace=None, projection=None, distinct=False)

Crea una instancia de la clase Query para recuperar entidades del almacén de datos de App Engine.

Si no se modifica más, el objeto de consulta resultante recuperará todas las entidades del tipo especificado por model_class. Los métodos de instancia filter(), ancestor(), y order() se pueden usar para personalizar la consulta con criterios de filtro adicionales, condiciones de ancestro y órdenes de clasificación.

Argumentos

model_class
Clase de modelo (o Expando) que representa el tipo de entidad al que se aplica la consulta.
keys_only
Si true, devuelve solo las claves en lugar de las entidades completas. Las consultas para obtener solo las claves son más rápidas y económicas que las que devuelven entidades completas.
cursor
Posición del cursor en la que se reanudará la consulta.
namespace
Espacio de nombres que se va a usar en la consulta.
proyección
Lista o tupla de nombres de propiedades que se van a devolver. Solo se devolverán las entidades que tengan las propiedades especificadas. Si no se especifica, se devuelven todas las entidades de forma predeterminada. Las consultas de proyección son más rápidas y económicas que las que devuelven entidades completas.

Nota: Si especifica este parámetro, es posible que cambien los requisitos de índice de la consulta.

distintas
En el caso de las consultas de proyección, distinct=True especifica que solo se devolverán resultados completamente únicos en un conjunto de resultados. Solo se devolverá el primer resultado de las entidades que tengan los mismos valores en las propiedades que se proyectan.
Verdadero
Devuelve solo el primer resultado de cada conjunto de valores distinto de las propiedades de la proyección.
Falso
Se devuelven todos los resultados.

Métodos de instancia

Las instancias de la clase Query tienen los siguientes métodos:

filter (property_operator, value)

Añade un filtro de propiedad a la consulta. La consulta solo devolverá las entidades cuyas propiedades cumplan todos sus filtros.

Argumentos

property_operator
Cadena formada por un nombre de propiedad y un operador de comparación opcional (=, !=, <, <=, >, >=, IN) separados por un espacio. Por ejemplo, 'age >'. Si solo se especifica un nombre de propiedad sin un operador de comparación, el filtro compara la igualdad (=) de forma predeterminada.
value
Valor con el que se comparará el valor de la propiedad. Por ejemplo:

q.filter('height >', 42).filter('city =', 'Seattle')
q.filter('user =', users.get_current_user())

El valor de comparación especificado debe ser del mismo tipo de valor que el de la propiedad que se está comparando.

ancestor (ancestor)

Añade un filtro de ancestro a la consulta. La consulta solo devolverá entidades con el ancestro especificado.

Argumento

ancestor
Entidad o clave antecesora.
order (property)

Añade un orden a la consulta. Si se añade más de un criterio de ordenación, se aplicarán en el orden especificado.

Argumento

property
Cadena que indica el nombre de la propiedad por la que se va a ordenar. Opcionalmente, se puede preceder de un guion (-) para especificar el orden descendente. Si se omite el guion, se especifica el orden ascendente de forma predeterminada. Por ejemplo:
# Order alphabetically by last name:
q.order('last_name')

# Order by height, tallest to shortest:
q.order('-height')
projection ()

Devuelve la tupla de propiedades de la proyección o None.

is_keys_only ()

Devuelve un valor booleano que indica si la consulta es una consulta de solo claves.

run (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=None, batch_size=20, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Devuelve un objeto iterable para recorrer los resultados de la consulta. Esto le permite especificar la operación de la consulta con los ajustes de los parámetros y acceder a los resultados de forma iterativa:

  1. Obtiene y descarta el número de resultados especificado por el argumento offset.
  2. Obtiene y devuelve hasta el número máximo de resultados especificado por el argumento limit.

Por lo tanto, el rendimiento del bucle se ajusta de forma lineal a la suma de offset + limit. Si sabes cuántos resultados quieres obtener, siempre debes definir un valor limit explícito.

Este método usa la prefetched asíncrona para mejorar el rendimiento. De forma predeterminada, obtiene los resultados de Datastore en pequeños lotes, lo que permite que la aplicación detenga la iteración y evite obtener más resultados de los necesarios.

Nota: Para obtener todos los resultados disponibles cuando se desconozca su número, asigna a batch_size un valor grande, como 1000.

Nota: Si no necesitas cambiar los valores de los argumentos predeterminados, puedes usar el objeto de consulta directamente como iterable para controlar el bucle. Esto llama implícitamente a run() con argumentos predeterminados.

Argumentos

read_policy
Lee la política que especifica el nivel de coherencia de datos que quieres:
STRONG_CONSISTENCY
Garantiza los resultados más recientes, pero solo se puede usar con un grupo de entidades.
EVENTUAL_CONSISTENCY
Puede abarcar varios grupos de entidades, pero puede devolver resultados obsoletos en ocasiones. Por lo general, las consultas de coherencia eventual se ejecutan más rápido que las de coherencia fuerte, pero no hay ninguna garantía.

Nota: Las consultas globales (no antecesoras) ignoran este argumento.

deadline
Tiempo máximo, en segundos, que debe esperar Datastore para devolver un resultado antes de cancelar la operación con un error. Acepta un número entero o un valor de punto flotante. No se puede definir un valor superior al predeterminado (60 segundos), pero se puede reducir para asegurarse de que una operación concreta falle rápidamente (por ejemplo, para devolver una respuesta más rápida al usuario, volver a intentar la operación, probar otra operación o añadir la operación a una cola de tareas).
offset
Número de resultados que se omitirán antes de devolver el primero.
limit
Número máximo de resultados que se devolverán. Si se omite o se le asigna el valor None, se recuperarán todos los resultados disponibles de forma predeterminada.
batch_size
Número de resultados que se intentarán obtener por lote. Si se define limit, se aplicará el límite especificado. De lo contrario, se aplicará 20 de forma predeterminada.
keys_only
Si true, devuelve solo las claves en lugar de las entidades completas. Las consultas para obtener solo las claves son más rápidas y económicas que las que devuelven entidades completas.
proyección
Lista o tupla de nombres de propiedades que se van a devolver. Solo se devolverán las entidades que tengan las propiedades especificadas. Si no se especifica, se devuelven todas las entidades de forma predeterminada. Las consultas de proyección son más rápidas y económicas que las que devuelven entidades completas.

Nota: Si especifica este parámetro, es posible que cambien los requisitos de índice de la consulta.

start_cursor
Posición del cursor en la que se debe iniciar la consulta.
end_cursor
Posición del cursor en la que finalizar la consulta.
get (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Ejecuta la consulta y devuelve el primer resultado o None si no se encuentra ningún resultado.

Argumentos

read_policy
Lee la política que especifica el nivel de coherencia de datos que quieres:
STRONG_CONSISTENCY
Garantiza los resultados más recientes, pero solo se puede usar con un grupo de entidades.
EVENTUAL_CONSISTENCY
Puede abarcar varios grupos de entidades, pero puede devolver resultados obsoletos en ocasiones. Por lo general, las consultas de coherencia eventual se ejecutan más rápido que las de coherencia fuerte, pero no hay ninguna garantía.

Nota: Las consultas globales (no antecesoras) ignoran este argumento.

deadline
Tiempo máximo, en segundos, que debe esperar Datastore para devolver un resultado antes de cancelar la operación con un error. Acepta un número entero o un valor de punto flotante. No se puede definir un valor superior al predeterminado (60 segundos), pero se puede reducir para asegurarse de que una operación concreta falle rápidamente (por ejemplo, para devolver una respuesta más rápida al usuario, volver a intentar la operación, probar otra operación o añadir la operación a una cola de tareas).
offset
Número de resultados que se omitirán antes de devolver el primero.
keys_only
Si true, devuelve solo las claves en lugar de las entidades completas. Las consultas para obtener solo las claves son más rápidas y económicas que las que devuelven entidades completas.
proyección
Lista o tupla de nombres de propiedades que se van a devolver. Solo se devolverán las entidades que tengan las propiedades especificadas. Si no se especifica, se devuelven todas las entidades de forma predeterminada. Las consultas de proyección son más rápidas y económicas que las que devuelven entidades completas.

Nota: Si especifica este parámetro, es posible que cambien los requisitos de índice de la consulta.

start_cursor
Posición del cursor en la que se debe iniciar la consulta.
end_cursor
Posición del cursor en la que finalizar la consulta.
fetch (limit, read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Ejecuta la consulta y devuelve una lista de resultados (que puede estar vacía):

  1. Obtiene y descarta el número de resultados especificado por el argumento offset.
  2. Obtiene y devuelve hasta el número máximo de resultados especificado por el argumento limit.

Por lo tanto, el rendimiento del método se escala de forma lineal con la suma de offset + limit.

Nota: Este método es solo un envoltorio fino alrededor del método run() y es menos eficiente y requiere más memoria que usar run() directamente. Rara vez necesitarás usar fetch(). Se proporciona principalmente para que te resulte más cómodo en los casos en los que necesites obtener una lista completa en memoria de los resultados de la consulta.

Nota: El método fetch() se ha diseñado para recuperar solo el número de resultados especificado por el argumento limit. Para obtener todos los resultados disponibles de una consulta cuando se desconoce su número, usa run() con un tamaño de lote grande, como run(batch_size=1000), en lugar de fetch().

Argumentos

limit
Número máximo de resultados que se devolverán. Si se le asigna el valor None, se recuperarán todos los resultados disponibles.
read_policy
Lee la política que especifica el nivel de coherencia de datos que quieres:
STRONG_CONSISTENCY
Garantiza los resultados más recientes, pero solo se puede usar con un grupo de entidades.
EVENTUAL_CONSISTENCY
Puede abarcar varios grupos de entidades, pero puede devolver resultados obsoletos en ocasiones. Por lo general, las consultas de coherencia eventual se ejecutan más rápido que las de coherencia fuerte, pero no hay ninguna garantía.

Nota: Las consultas globales (no antecesoras) ignoran este argumento.

deadline
Tiempo máximo, en segundos, que debe esperar Datastore para devolver un resultado antes de cancelar la operación con un error. Acepta un número entero o un valor de punto flotante. No se puede definir un valor superior al predeterminado (60 segundos), pero se puede reducir para asegurarse de que una operación concreta falle rápidamente (por ejemplo, para devolver una respuesta más rápida al usuario, volver a intentar la operación, probar otra operación o añadir la operación a una cola de tareas).
offset
Número de resultados que se omitirán antes de devolver el primero.
keys_only
Si true, devuelve solo las claves en lugar de las entidades completas. Las consultas para obtener solo las claves son más rápidas y económicas que las que devuelven entidades completas.
proyección
Lista o tupla de nombres de propiedades que se van a devolver. Solo se devolverán las entidades que tengan las propiedades especificadas. Si no se especifica, se devuelven todas las entidades de forma predeterminada. Las consultas de proyección son más rápidas y económicas que las que devuelven entidades completas.

Nota: Si especifica este parámetro, es posible que cambien los requisitos de índice de la consulta.

start_cursor
Posición del cursor en la que se debe iniciar la consulta.
end_cursor
Posición del cursor en la que finalizar la consulta.
count (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=1000, start_cursor=None, end_cursor=None)

Devuelve el número de resultados que coinciden con la consulta. Es más rápido por un factor constante que recuperar todos los resultados, pero el tiempo de ejecución sigue aumentando de forma lineal con la suma de offset + limit. A menos que se espere que el número de resultados sea pequeño, es mejor especificar un argumento limit. De lo contrario, el método continuará hasta que termine de contar o se agote el tiempo de espera.

Argumentos

read_policy
Lee la política que especifica el nivel de coherencia de datos que quieres:
STRONG_CONSISTENCY
Garantiza los resultados más recientes, pero solo se puede usar con un grupo de entidades.
EVENTUAL_CONSISTENCY
Puede abarcar varios grupos de entidades, pero puede devolver resultados obsoletos en ocasiones. Por lo general, las consultas de coherencia eventual se ejecutan más rápido que las de coherencia fuerte, pero no hay ninguna garantía.

Nota: Las consultas globales (no antecesoras) ignoran este argumento.

deadline
Tiempo máximo, en segundos, que debe esperar Datastore para devolver un resultado antes de cancelar la operación con un error. Acepta un número entero o un valor de punto flotante. No se puede definir un valor superior al predeterminado (60 segundos), pero se puede reducir para asegurarse de que una operación concreta falle rápidamente (por ejemplo, para devolver una respuesta más rápida al usuario, volver a intentar la operación, probar otra operación o añadir la operación a una cola de tareas).
offset
Número de resultados que se omitirán antes de contabilizar el primero.
limit
Número máximo de resultados que se contabilizarán.
start_cursor
Posición del cursor en la que se debe iniciar la consulta.
end_cursor
Posición del cursor en la que finalizar la consulta.
index_list ()

Devuelve una lista de los índices utilizados por una consulta ejecutada, incluidos los índices primarios, compuestos, de tipo y de una sola propiedad.

Precaución: Si invocas este método en una consulta que aún no se ha ejecutado, se generará una excepción AssertionError.

Nota: Esta función no es totalmente compatible con el servidor de desarrollo. Cuando se usa con el servidor de desarrollo, el resultado es una lista vacía o una lista que contiene exactamente un índice compuesto.

Por ejemplo, el siguiente código imprime información variada sobre los índices que usa una consulta:

# other imports ...
import webapp2
from google.appengine.api import users
from google.appengine.ext import db

class Greeting(db.Model):
  author = db.StringProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):
  def get(self):
    user = users.get_current_user()
    q = db.Query(Greeting)
    q.filter("author =", user.user_id())
    q.order("-date")
    q.fetch(100)
    index_list = q.index_list()
    for ix in index_list:
      self.response.out.write("Kind: %s" % ix.kind())
      self.response.out.write("<br />")
      self.response.out.write("Has ancestor? %s" % ix.has_ancestor())
      self.response.out.write("<br />")
      for name, direction in ix.properties():
        self.response.out.write("Property name: "+name)
        self.response.out.write("<br />")
        if direction == db.Index.DESCENDING:
          self.response.out.write("Sort direction: DESCENDING")
        else:
          self.response.out.write("Sort direction: ASCENDING")
        self.response.out.write("<br />")

De esta forma, se genera una salida como la siguiente para cada índice:

Kind: Greeting
Has ancestor? False
Property name: author
Sort direction: ASCENDING
Property name: date
Sort direction: DESCENDING
cursor ()

Devuelve una cadena de cursor codificada en base64 que indica la posición en el conjunto de resultados de la consulta después del último resultado obtenido. La cadena de cursor se puede usar de forma segura en los parámetros GET y POST de HTTP, y también se puede almacenar en Datastore o Memcache. En una invocación futura de la misma consulta, se puede proporcionar esta cadena a través del parámetro start_cursor o del método with_cursor() para reanudar la obtención de resultados desde esta posición.

Precaución: Si invocas este método en una consulta que aún no se ha ejecutado, se generará una excepción AssertionError.

Nota: No todas las consultas son compatibles con los cursores. Consulta la página Consultas de Datastore para obtener más información.

with_cursor (start_cursor, end_cursor=None)

Especifica las posiciones de inicio y (opcionalmente) de finalización dentro del conjunto de resultados de una consulta desde las que se deben obtener los resultados. Las cadenas de cursor que indican las posiciones inicial y final se pueden obtener llamando a cursor() después de una invocación anterior de la consulta. La consulta actual debe ser idéntica a la invocación anterior, incluido el tipo de entidad, los filtros de propiedad, los filtros de ancestro y los criterios de ordenación.

Argumentos

start_cursor
Cadena de cursor codificada en Base64 que especifica dónde empezar la consulta.
end_cursor
Cadena de cursor codificada en base64 que especifica dónde finalizar la consulta.