Documentation de référence GQL pour Python NDB/DB

GQL est un langage de type SQL permettant de récupérer des entités et des clés. La syntaxe des requêtes GQL est semblable à celle de SQL. Cette page est une documentation de référence pour l'utilisation de GQL avec les bibliothèques clientes NDB et DB de Python.

GQL correspond approximativement à SQL. Vous pouvez considérer un genre (kind) GQL comme une table SQL, une entité (entity) GQL comme une ligne SQL et une propriété (property) GQL comme une colonne SQL. Toutefois, une recherche d'intersection ligne-colonne SQL est représentée par une valeur unique, alors qu'une valeur de propriété peut correspondre à une liste dans GQL.

Versions de GQL

Différentes versions de GQL sont requises selon l'emplacement où vous exécutez les requêtes. Il existe deux documentations de référence GQL :

Syntaxe

La syntaxe GQL pour Python NDB/DB peut être résumée comme suit :

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> ...]])

Comme avec le SQL, les mots clés GQL ne sont pas sensibles à la casse. En revanche, les noms de genre et de propriété sont sensibles à la casse.

GQL n'accepte que les instructions SELECT.

Les requêtes GQL renvoient zéro, une ou plusieurs entités entières, entités projetées ou clés du genre demandé. Chacune d'elles commence toujours par SELECT *, SELECT __key__ ou SELECT <property list>, où property correspond à une liste d'une ou de plusieurs propriétés d'entité séparées par une virgule qui doivent être renvoyées par la requête. Une requête GQL ne peut pas exécuter une requête JOIN de type SQL.

Conseil : Les requêtes SELECT __key__ or SELECT <property list> sont plus rapides et utilisent moins de temps CPU que les requêtes SELECT *.

La clause DISTINCT (expérimentale) facultative spécifie que seuls les résultats totalement uniques sont renvoyés dans un ensemble de résultats. La requête ne renvoie que le premier résultat des entités dont les valeurs des propriétés en cours de projection sont identiques.

La clause FROM facultative limite l'ensemble de résultats aux entités du genre spécifié. Une requête sans clause FROM est appelée "requête sans genre" et ne peut comporter qu'une clause WHERE qui spécifie une propriété __key__.

La clause WHERE facultative limite l'ensemble de résultats aux entités remplissant une ou plusieurs conditions. Chaque condition compare une propriété de l'entité à une valeur au moyen d'un opérateur de comparaison. Si le mot clé AND est associé à plusieurs conditions, une entité doit remplir toutes les conditions pour être renvoyée par la requête. GQL n'utilise pas d'opérateur OR, mais un opérateur IN, qui correspond à une forme limitée de OR.

L'opérateur IN compare la valeur d'une propriété à chaque élément d'une liste. L'opérateur IN équivaut à plusieurs requêtes = (une pour chaque valeur), liées les unes aux autres par l'opérateur OR. La requête peut renvoyer une entité dont la valeur pour la propriété donnée est égale à l'une des valeurs de la liste.

Remarque : Les opérateurs IN et != utilisent plusieurs requêtes en arrière-plan. Par exemple, l'opérateur IN exécute une requête de datastore sous-jacente distincte pour chaque élément de la liste. Les entités renvoyées correspondent à un résultat du produit croisé de toutes les requêtes de datastore sous-jacentes et sont dédupliquées. 30 requêtes de datastore sont autorisées au maximum pour une même requête GQL.

Un critère peut également vérifier si une entité a pour ancêtre une entité donnée, à l'aide de l'opérateur ANCESTOR IS. La valeur est une instance de modèle ou une clé de l'entité ancêtre. Pour en savoir plus sur les ancêtres, consultez la page sur les clés et groupes d'entités.

Le côté gauche d'une comparaison est toujours un nom de propriété. Un nom de propriété se compose généralement de caractères alphanumériques éventuellement combinés à des traits de soulignement et des points. En d'autres termes, il correspond à l'expression régulière [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*.

Attention : Les noms de propriété contenant d'autres caractères imprimables doivent être entourés par des guillemets doubles. Par exemple, "first-name". Les espaces ou les caractères non imprimables ne sont pas acceptés dans les noms de propriété.

Le côté droit d'une comparaison peut correspondre à l'un des éléments suivants (selon le type de données de la propriété) :

  • Un littéral str, sous la forme d'une chaîne entourée par des guillemets simples. Les caractères entre guillemets simples de la chaîne doivent être échappés comme suit : ''. Par exemple, 'Joe''s Diner'.
  • Un entier ou un littéral de nombre à virgule flottante. Par exemple, 42.7.
  • Un littéral booléen tel que TRUE ou FALSE.
  • Le littéral NULL, qui représente la valeur nulle (None en Python).
  • Un littéral de date et d'heure, de date ou d'heure associé à des valeurs numériques ou une chaîne aux formats suivants :
    • 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 littéral de clé d'entité associé à une clé encodée sous forme de chaîne ou à un chemin complet de genres et de noms/ID de clés :

    • KEY('encoded key')
    • KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
  • Un littéral d'objet User associé à l'adresse e-mail de l'utilisateur :
    USER('email-address')
  • Un littéral GeoPt associé à la latitude et la longitude sous forme de valeurs à virgule flottante :
    GEOPT(lat, long)
  • Une valeur de paramètre lié. Dans la chaîne de requête, les paramètres de position sont référencés par un nombre : title = :1. Les paramètres de mot clé sont référencés par un nom : title = :mytitle.

Remarque : Les conditions au format property = NULL vérifient si une valeur nulle est explicitement stockée dans le datastore de la propriété. Cette vérification est différente de celle qui consiste à vérifier s'il manque une valeur pour la propriété dans l'entité ! Les requêtes de datastore qui font référence à une propriété ne renvoient jamais d'entités qui ne comportent pas de valeur pour cette propriété.

Les paramètres peuvent être liés en tant qu'arguments de position ou de mot clé transmis au constructeur GqlQuery ou à la méthode gql() d'une classe de modèle. Les types de données de propriétés pour lesquels il n'existe aucune syntaxe de littéral de valeur correspondante doivent être indiqués à l'aide d'une liaison de paramètre, y compris le type de données "List". Les paramètres peuvent être liés de nouveau à d'autres valeurs pendant la durée de vie de l'instance de GqlQuery (pour qu'une requête puisse être efficacement réutilisée, par exemple) à l'aide de la méthode bind().

La clause ORDER BY facultative indique que les résultats doivent être renvoyés après avoir été triés selon les propriétés spécifiées, par ordre croissant (ASC) ou décroissant (DESC). La clause ORDER BY peut indiquer plusieurs ordres de tri sous forme de liste de valeurs séparées par des virgules, évalués de gauche à droite. Si le sens de tri n'est pas précisé, il prend par défaut la valeur ASC. Si aucune clause ORDER BY n'est indiquée, l'ordre des résultats est indéterminé et peut varier dans le temps.

Une clause facultative LIMIT engendre une interruption du renvoi de résultats par la requête après les premières entités <count>. LIMIT peut également inclure une valeur <offset> qui indique le nombre de résultats à ignorer afin de trouver le premier résultat à renvoyer. Une clause OFFSET facultative permet d'indiquer un <offset> en l'absence de clause LIMIT.

Remarque : Comme le paramètre offset de la méthode fetch(), la clause OFFSET d'une chaîne de requête GQL ne réduit pas le nombre d'entités extraites du datastore. Elle n'a d'incidence que sur la sélection des résultats renvoyés par la méthode fetch(). Une requête utilisant un décalage présente des caractéristiques de performances qui correspondent linéairement à celles obtenues avec le décalage et la limite.

Pour en savoir plus sur l'exécution des requêtes GQL, sur les paramètres de liaison et sur l'accès aux résultats, reportez-vous à la classe GqlQuery et à la méthode de classe Model.gql().

Exemples

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

Pour rechercher toutes les entités du genre Person dont les âges sont compris entre 18 et 35 ans (c'est-à-dire Charlie et Edna), utilisez la requête suivante :

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

Pour trouver les trois entités du genre Person qui sont les plus âgées (c'est-à-dire Amy, Betty et Charlie), utilisez la requête suivante :

SELECT * FROM Person ORDER BY age DESC LIMIT 3

Pour trouver les entités du genre Person dont le nom est "Betty" ou "Charlie", utilisez la requête suivante :

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

Pour ne renvoyer que les valeurs name de chaque entité Person, utilisez la requête suivante :

SELECT name FROM Person

Pour ne renvoyer que les valeurs name de chaque entité Person classées selon le critère age, utilisez la requête suivante :

SELECT name FROM Person ORDER BY age

Pour trouver les clés des entités du genre Person dont l'âge est défini sur None (par exemple, KEY('Person', 'georgemichael')), utilisez la requête suivante :

SELECT __key__ FROM Person WHERE age = NULL

Pour trouver toutes les entités, quel que soit leur genre, qui appartiennent au groupe d'entités d'Amy (c'est-à-dire Amy et Fred), utilisez la requête suivante :

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

Pour rechercher des correspondances par clé, vous pouvez utiliser __key__ dans la partie gauche d'une condition. Par exemple, la requête suivante permet d'obtenir toutes les entités Person dont le nom d'utilisateur commence par "a" :

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

Remarque : Si vous créez une requête avec une égalité sur __key__, utilisez plutôt get() pour récupérer directement l'entité.