Referencia de GQL para Python NDB/DB

GQL es un lenguaje similar a SQL que se usa para obtener entidades y claves. La sintaxis de las consultas de GQL es similar a la de SQL. Esta página es una referencia para usar GQL con las bibliotecas de cliente NDB y DB de Python.

GQL se corresponde aproximadamente con SQL: puedes considerar un kind de GQL como una tabla de SQL, un entity de GQL como una fila de SQL y un property de GQL como una columna de SQL. Sin embargo, una búsqueda de fila y columna de SQL es un valor único, mientras que en GQL el valor de una propiedad puede ser una lista.

Versiones de GQL

Necesitas diferentes versiones de GQL en función de dónde ejecutes las consultas. Hay dos referencias de GQL:

Sintaxis

La sintaxis de GQL para Python NDB/DB se puede resumir de la siguiente manera:

SELECT [DISTINCT] [* | <property list> | __key__]
  [FROM <kind>]
  [WHERE <condition> [AND <condition> ...]]
  [ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
  [LIMIT [<offset>,]<count>]
  [OFFSET <offset>]

  <property list> := <property> [, <property> ...]
  <condition> := <property> {< | <= | > | >= | = | != } <value>
  <condition> := <property> IN <list>
  <condition> := ANCESTOR IS <entity or key>
  <list> := (<value> [, <value> ...]])

Al igual que sucede con SQL, en las palabras clave de GQL no se distingue entre mayúsculas y minúsculas. En los nombres de tipo y de propiedad se distingue entre mayúsculas y minúsculas.

GQL solo admite instrucciones SELECT.

Una consulta GQL devuelve cero o más entidades completas, entidades proyectadas, o claves del tipo solicitado. Todas las consultas de GQL empiezan por SELECT *, SELECT __key__ o SELECT <property list>, donde property es una lista delimitada por comas de una o varias propiedades de entidad que se devolverán en la consulta. (Una consulta de GQL no puede realizar una consulta de tipo "join" de SQL).

Nota: Las consultas SELECT __key__ or SELECT <property list> son más rápidas y usan menos tiempo de CPU que las consultas SELECT *.

La cláusula opcional DISTINCT(experimental) 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.

La cláusula opcional FROM limita el conjunto de resultados a las entidades del tipo indicado. Una consulta sin cláusula FROM se denomina consulta sin tipo y solo puede tener un WHERE que especifique una propiedad __key__.

La cláusula opcional WHERE limita el conjunto de resultados a las entidades que cumplen una o varias condiciones. Cada condición compara una propiedad de la entidad con un valor mediante un operador de comparación. Si se proporcionan varias condiciones con la palabra clave AND, una entidad debe cumplir todas las condiciones para que la consulta la devuelva. GQL no tiene un operador OR. Sin embargo, sí tiene un operador IN, que proporciona una forma limitada de OR.

El operador IN compara el valor de una propiedad con cada elemento de una lista. El operador IN equivale a muchas consultas =, una por cada valor, que se combinan con el operador O. Se puede devolver una entidad cuya propiedad tenga un valor igual a cualquiera de los valores de la lista.

Nota: Los operadores IN y != usan varias consultas en segundo plano. Por ejemplo, el operador IN ejecuta una consulta de almacén de datos subyacente independiente para cada elemento de la lista. Las entidades devueltas son el resultado del producto cruzado de todas las consultas de almacén de datos subyacentes y se eliminan los duplicados. Se permite un máximo de 30 consultas de almacén de datos por consulta de GQL.

Una condición también puede comprobar si una entidad tiene una entidad determinada como antecesor mediante el operador ANCESTOR IS. El valor es una instancia de modelo o una clave de la entidad antecesora. Para obtener más información sobre los ancestros, consulta Claves y grupos de entidades.

La parte izquierda de una comparación siempre se compone de un nombre de propiedad. Un nombre de propiedad típico consta de caracteres alfanuméricos que se pueden combinar con guiones bajos y puntos. Es decir, coinciden con la expresión regular [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*.

Precaución: Los nombres de propiedades que contengan otros caracteres imprimibles deben incluirse entre comillas dobles. Por ejemplo: "first-name". No se admiten espacios ni caracteres no imprimibles en los nombres de las propiedades.

El lado derecho de una comparación puede ser uno de los siguientes (según el tipo de datos de la propiedad):

  • un literal str, como una cadena entre comillas simples. Los caracteres de comillas simples de la cadena deben tener el formato de escape ''. Por ejemplo: 'Joe''s Diner'
  • Un valor literal de número de punto flotante o entero. Por ejemplo: 42.7
  • Un literal booleano, como TRUE o FALSE.
  • El literal NULL, que representa el valor nulo (None en Python).
  • un literal de fecha y hora, fecha u hora, con valores numéricos o una representación de cadena, en los siguientes formatos:
    • DATETIME(year, month, day, hour, minute, second)
    • DATETIME('YYYY-MM-DD HH:MM:SS')
    • DATE(year, month, day)
    • DATE('YYYY-MM-DD')
    • TIME(hour, minute, second)
    • TIME('HH:MM:SS')
  • Un literal de clave de entidad, con una clave codificada como cadena o una ruta completa de tipos y nombres o IDs de clave:

    • KEY('encoded key')
    • KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
  • Un literal de objeto User con la dirección de correo del usuario:
    USER('email-address')
  • Un literal GeoPt, con la latitud y la longitud como valores de punto flotante:
    GEOPT(lat, long)
  • Un valor de parámetro enlazado. En la cadena de consulta, los parámetros posicionales se referencian por número: title = :1. Los parámetros de palabra clave se referencian por nombre: title = :mytitle.

Nota: Las condiciones de la forma property = NULL comprueban si se almacena explícitamente un valor nulo en el almacén de datos de esa propiedad. Este proceso no es similar a comprobar si la entidad carece de valores para la propiedad. Las consultas de Datastore que hacen referencia a una propiedad nunca devuelven entidades que no tengan algún valor para esa propiedad.

Los parámetros enlazados se pueden enlazar como argumentos posicionales o argumentos de palabras clave que se pasan a el constructor GqlQuery o al método gql() de una clase de modelo. Los tipos de datos de propiedad que no tengan una sintaxis literal de valor correspondiente se deben especificar mediante la vinculación de parámetros, incluido el tipo de datos de lista. Los enlaces de parámetros se pueden volver a enlazar con nuevos valores durante el tiempo de vida de la instancia GqlQuery (por ejemplo, para reutilizar una consulta de forma eficiente) mediante el método bind().

La cláusula opcional ORDER BY indica que los resultados deben devolverse ordenados por las propiedades especificadas, en orden ascendente (ASC) o descendente (DESC). La cláusula ORDER BY puede especificar varios criterios de ordenación como una lista delimitada por comas, que se evalúa de izquierda a derecha. Si no se especifica la dirección, se utiliza ASC de forma predeterminada. Si no se especifica ninguna cláusula ORDER BY, el orden de los resultados no está definido y puede cambiar con el tiempo.

Una cláusula LIMIT opcional hace que la consulta deje de devolver resultados después de las primeras <count> entidades. La cláusula LIMIT también puede incluir un <offset> para saltar ese número de resultados y encontrar el primero que se debe devolver. Una cláusula OFFSET opcional puede especificar un <offset> si no hay ninguna cláusula LIMIT.

Nota: Al igual que el parámetro offset del método fetch(), un OFFSET en una cadena de consulta de GQL no reduce el número de entidades obtenidas del almacén de datos. Solo afecta a los resultados que devuelve el método fetch(). Una consulta con un desplazamiento tiene características de rendimiento que corresponden linealmente con el tamaño del desplazamiento más el tamaño del límite.

Para obtener información sobre cómo ejecutar consultas de GQL, enlazar parámetros y acceder a los resultados, consulta la clase GqlQuery y el método de clase Model.gql().

Ejemplos

from google.appengine.ext import db

class Person(db.Model):
  name = db.StringProperty()
  age = db.IntegerProperty()

# We use a unique username for the Entity's key.
amy = Person(key_name='amym', name='Amy', age=48)
amy.put()
Person(key_name='bettyd', name='Betty', age=42).put()
Person(key_name='charliec', name='Charlie', age=32).put()
Person(key_name='charliek', name='Charlie', age=29).put()
Person(key_name='eedna', name='Edna', age=20).put()
Person(key_name='fredm', name='Fred', age=16, parent=amy).put()
Person(key_name='georgemichael', name='George').put()

Para encontrar todas las entidades del tipo Person cuya edad esté comprendida entre 18 y 35 años (es decir, tanto Charlie como Edna), usa esta consulta:

SELECT * FROM Person WHERE age >= 18 AND age <= 35

Para encontrar las tres entidades de tipo Person cuya edad sea la mayor (es decir, Amy, Betty y Charlie), usa esta consulta:

SELECT * FROM Person ORDER BY age DESC LIMIT 3

Para encontrar las entidades de tipo Person cuyos nombres sean "Betty" o "Charlie", usa esta consulta:

SELECT * FROM Person WHERE name IN ('Betty', 'Charlie')

Para devolver solo los valores de name de cada Person, usa esta consulta:

SELECT name FROM Person

Para devolver solo los valores de name de cada Person, ordenados por age, usa esta consulta:

SELECT name FROM Person ORDER BY age

Para encontrar las claves de las entidades de tipo Person que tengan una edad de None (es decir, KEY('Person', 'georgemichael')), usa esta consulta:

SELECT __key__ FROM Person WHERE age = NULL

Para encontrar todas las entidades, independientemente del tipo, que estén en el grupo de entidades de Amy (es decir, Amy y Fred), usa esta consulta:

SELECT * WHERE __key__ HAS ANCESTOR KEY(Person, 'Amy')

Para buscar coincidencias por clave, podemos usar __key__ en la parte izquierda de una condición. Por ejemplo, podemos usarlo para obtener todas las entidades Person que tengan un nombre de usuario que empiece por "a".

SELECT * FROM Person WHERE __key__ >= KEY('Person', 'a') AND __key__ < KEY('Person', 'b')

Nota: Si alguna vez creas una consulta con una igualdad en __key__, te recomendamos que uses get() para obtener la entidad directamente.