Referencia de GQL para NDB/DB de Python

GQL es un lenguaje similar a SQL para recuperar entidades y claves. La sintaxis de las consultas de GQL es similar a la de SQL. Esta página es una referencia sobre el uso de GQL con las bibliotecas cliente de NDB y DB para Python.

GQL resulta más o menos parecido a SQL: puedes pensar en un kind de GQL como una tabla de SQL, en una entity de GQL como una fila de SQL y en una property de GQL como una columna de SQL. Sin embargo, una búsqueda de fila-columna de SQL es un valor único, mientras que en GQL un valor de propiedad puede ser una lista.

Versiones de GQL

Necesitas diferentes versiones de GQL según donde ejecutes las consultas. Existen dos referencias de GQL:

Sintaxis

La sintaxis de GQL para NDB/DB de Python 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 con SQL, las palabras clave de GQL no distinguen entre mayúsculas y minúsculas. Los nombres de tipo y propiedad distinguen entre mayúsculas y minúsculas.

GQL solo admite sentencias SELECT.

Una consulta de GQL muestra cero o más entidades completas, entidades proyectadas o claves de la categoría solicitada. Cada consulta de GQL siempre comienza con SELECT *, SELECT __key__ o SELECT <property list>, en la que property es una lista delimitada por comas de una o más propiedades de entidades que mostrará la consulta. (una consulta de GQL no puede realizar una consulta de “unión” similar a la de SQL).

Sugerencia: 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 DISTINCT(experimental) opcional especifica que solo los resultados únicos en su totalidad se mostrarán en un conjunto de resultados. Esto solo mostrará el primer resultado para las entidades que tienen los mismos valores en las propiedades que se están proyectando.

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

La cláusula WHERE opcional limita el conjunto de resultados a aquellas entidades que cumplen con una o más condiciones. Cada condición compara una propiedad de la entidad con un valor mediante el uso de un operador de comparación. Si se dan varias condiciones con la palabra clave AND, una entidad debe cumplir con todas las condiciones para que la consulta la muestre en sus resultados. GQL no tiene un operador OR. Sin embargo, 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 es equivalente a muchas consultas =, una para cada valor, que se unen mediante OR. Una entidad cuyo valor para la propiedad dada es igual a cualquiera de los valores en la lista puede mostrarse en la consulta.

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

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

El lado izquierdo de una comparación es siempre un nombre de propiedad. Un nombre de propiedad típico consiste en caracteres alfanuméricos combinados de manera opcional con guiones bajos y puntos. En otras palabras, coinciden con la expresión regular [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*.

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

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

  • Un literal str, como una string entre comillas simples. Los caracteres de comillas simples en la string deben escaparse como ''. Por ejemplo: 'Joe''s Diner'
  • un número entero o un número de punto flotante literal. 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, hora o de fecha y hora, con valores numéricos o una representación de string, 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 en string o una ruta completa de tipos y nombres/ID de clave:

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

Nota: Las condiciones con el formato property = NULL comprueban si un valor nulo se almacena de forma explícita en el almacén de datos para esa propiedad. Esto no es lo mismo que verificar si la entidad carece de valor para la propiedad. Las consultas del almacén de datos que se refieren a una propiedad nunca muestran entidades que no tengan algún valor para esa propiedad.

Los parámetros vinculados se pueden vincular como argumentos posicionales o argumentos de palabras clave que se pasan al constructor de GqlQuery o a un método gql() de una clase de modelo. Los tipos de datos de propiedad que no tienen la sintaxis literal de valor correspondiente deben especificarse con la vinculación de parámetros, que incluye el tipo de datos de lista. Las vinculaciones de parámetros pueden volver a vincularse con valores nuevos durante el ciclo de vida de la instancia de GqlQuery (como, por ejemplo, para volver a usar una consulta de manera eficiente) mediante el método bind().

La cláusula ORDER BY opcional indica que los resultados se deben mostrar ordenados por las propiedades determinadas, ya sea en orden ascendente (ASC) o descendente (DESC). La cláusula ORDER BY puede especificar varios órdenes de clasificación como una lista delimitada por comas, que se evalúa de izquierda a derecha. Si no se especifica la dirección, el valor predeterminado es ASC. Si no se especifica una cláusula ORDER BY, el orden de los resultados es indefinido y puede cambiar con el tiempo.

Una cláusula LIMIT opcional hace que la consulta deje de mostrar resultados después de las primeras entidades <count>. La cláusula LIMIT también puede incluir un <offset> para omitir esa cantidad de resultados y encontrar el primer resultado que se mostrará. Una cláusula OFFSET opcional puede especificar un <offset> si no hay una cláusula LIMIT.

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

Para obtener información sobre la ejecución de consultas de GQL, la vinculación de parámetros y el acceso a los resultados, consulta la clase GqlQuery y el método de Model.gql() de la clase.

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 que se busquen todas las entidades de la categoría Person cuyas edades estén entre los 18 y los 35 años (es decir, Charly y Edna), usa esta consulta:

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

Para que se busquen las tres entidades de la categoría Person cuyas edades sean las más altas (es decir, Amy, Betty y Charlie), usa esta consulta:

SELECT * FROM Person ORDER BY age DESC LIMIT 3

Para que se busquen las entidades de la categoría Person cuyos nombres sean “Betty” o “Charlie”, usa esta consulta:

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

Para que se muestren solo los valores name de cada Person, usa esta consulta:

SELECT name FROM Person

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

SELECT name FROM Person ORDER BY age

Para que se busquen las claves de las entidades de la categoría Person cuyo valor de edad es None (es decir, KEY('Person', 'georgemichael')), usa esta consulta:

SELECT __key__ FROM Person WHERE age = NULL

Para encontrar todas las entidades, sin importar la categoría, 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 hacer coincidir por clave, podemos usar __key__ en el lado izquierdo de una condición. Por ejemplo, podemos usarlo para obtener todas las entidades Person que tengan un nombre de usuario que comienza con “a”.

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

Nota: Si alguna vez compilas una consulta con igualdad en __key__, considera usar get() en su lugar para recuperar la entidad directamente.