Classe Query

Remarque : Les développeurs qui créent des applications sont vivement encouragés à utiliser la bibliothèque cliente NDB qui présente plusieurs avantages supplémentaires par rapport à cette bibliothèque cliente, tels que la mise en cache automatique des entités via l'API Memcache. Si vous utilisez actuellement l'ancienne bibliothèque cliente DB, consultez le guide de migration de DB vers NDB.

La classe Query représente une requête permettant de récupérer des entités depuis App Engine Datastore. (Consultez également la documentation sur la classe associée GqlQuery, qui définit des requêtes à l'aide de GQL, un langage de requête de type SQL.)

La classe Query est définie dans le module google.appengine.ext.db.

Remarque : Le mécanisme de requête basé sur les index permet l'exécution d'un large éventail de requêtes et convient à la plupart des applications. Toutefois, il n'est pas compatible avec certains genres de requêtes couramment rencontrés dans d'autres technologies de base de données. Plus précisément, les requêtes de jointure et d'agrégation ne sont pas acceptées dans le moteur de requêtes en mode Datastore. Pour connaître les limites associées aux requêtes Datastore, consultez la page Requêtes Datastore.

Présentation

Une application crée un objet de requête pour un genre d'entité donné en appelant directement le constructeur de Query.

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

q = db.Query(Song)

L'application peut également appeler la méthode de classe all() de la classe de modèle du genre :

q = Song.all()

Si vous n'effectuez pas d'autre modification, l'instance obtenue de la classe Query récupère toutes les entités existantes du genre spécifié. Vous pouvez ensuite appeler des méthodes afin de personnaliser la requête avec des critères de filtrage, des conditions d'ancêtre et des ordres de tri supplémentaires :

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

Pour plus de simplicité, toutes ces méthodes renvoient l'objet de requête lui-même, ce qui vous permet de les placer de façon successive au sein d'une même instruction :

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

L'application peut ensuite exécuter la requête et accéder aux résultats de l'une des manières suivantes :

  • Utilisez l'objet de requête comme un itérable afin de traiter les entités correspondantes une par une :

    for song in q:
      print song.title

    Ce code appelle implicitement la méthode run() de la requête pour générer les entités correspondantes. Il est comparable au contenu suivant :

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

    L'argument de mot-clé limit vous permet de définir une limite du nombre de résultats à traiter :

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

    L'interface de l'itérateur ne met pas en cache les résultats. Par conséquent, la création d'un itérateur à partir de l'objet de requête a pour effet de réitérer la même requête depuis le début.

  • Appelez la méthode get() de la requête pour obtenir la première entité correspondante trouvée dans le datastore :

    song = q.get()
    print song.title
  • Appelez la méthode fetch() de la requête pour obtenir la liste de toutes les entités correspondantes jusqu'à un nombre défini de résultats :

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

    Comme avec run(), l'objet de requête ne met pas en cache les résultats. Le fait d'appeler fetch() une seconde fois a pour effet de renvoyer la même requête.

    Remarque : Il est rare d'avoir besoin de cette méthode. Il est presque toujours préférable d'utiliser run().

Constructeur

Le constructeur de la classe Query est défini comme suit :

class Query (model_class=None, keys_only=False, cursor=None, namespace=None, projection=None, distinct=False)

Crée une instance de la classe Query permettant de récupérer des entités à partir d'App Engine Datastore.

Si vous n'effectuez pas d'autre modification, l'objet de requête obtenu récupère toutes les entités existantes du genre spécifié par model_class. Les méthodes d'instance filter(), ancestor(), et order() peuvent ensuite être utilisées pour personnaliser la requête avec des critères de filtrage, des conditions d'ancêtre et des ordres de tri supplémentaires.

Arguments

model_class
La classe Model (ou Expando) représente le genre d'entité auquel s'applique la requête.
keys_only
Si la valeur est true, ne renvoie que des clés au lieu d'entités complètes. Les requêtes portant uniquement sur des clés sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.
cursor
Position du curseur à laquelle reprendre la requête.
namespace
Espace de noms à utiliser pour la requête.
projection
Liste ou tuple de noms de propriétés à renvoyer. Seules les entités possédant les propriétés spécifiées sont renvoyées. Si cet argument n'est pas spécifié, les entités entières sont renvoyées par défaut. Les requêtes portant sur des projections sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.

Remarque : La spécification de ce paramètre peut modifier les exigences d'index de la requête.

distinct
Dans le cas de requêtes de projection, la valeur distinct=True spécifie que seuls les résultats totalement uniques sont renvoyés dans un ensemble de résultats. Grâce à cette méthode, seul le premier résultat des entités dont les valeurs des propriétés en cours de projection sont identiques est renvoyé.
True
Ne renvoie que le premier résultat de chaque ensemble de valeurs distinct pour les propriétés de la projection.
Faux
Renvoie tous les résultats.

Méthodes des instances

Les instances de la classe Query utilisent les méthodes suivantes :

filter (property_operator, value)

Ajoute un filtre de propriété à la requête. La requête ne renvoie que les entités dont les propriétés satisfont à l'ensemble des filtres.

Arguments

property_operator
Chaîne composée d'un nom de propriété et d'un opérateur de comparaison facultatif (=, !=, <, <=, >, >=, IN), séparés par un espace. Par exemple, 'age >'. Si seul un nom de propriété est spécifié, le filtre recherche des valeurs égales (=) par défaut.
value
Valeur à comparer avec la valeur de propriété. Exemple :

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

La valeur de comparaison spécifiée doit posséder le même type que celui de la propriété comparée.

ancestor (ancestor)

Ajoute un filtre d'ancêtre à la requête. La requête ne renvoie que les entités avec l'ancêtre spécifié.

Argument

ancestor
Entité ou clé d'ancêtre.
order (property)

Ajoute un ordre de tri à la requête. Si plusieurs ordres de tri sont ajoutés, ils sont appliqués dans l'ordre spécifié.

Argument

property
Chaîne fournissant le nom de la propriété utilisée pour le tri, éventuellement précédée d'un trait d'union (-) pour spécifier l'ordre décroissant. En cas d'omission du trait d'union, l'ordre croissant est la valeur par défaut. Exemple :
# Order alphabetically by last name:
q.order('last_name')

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

Renvoie le tuple de propriétés dans la projection ou None.

is_keys_only ()

Renvoie une valeur booléenne indiquant si la requête ne contient que des clés.

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)

Renvoie un itérable afin d'effectuer une boucle sur les résultats de la requête. Cela permet de spécifier le fonctionnement de la requête avec des paramètres et d'accéder aux résultats de manière itérative :

  1. Récupère et supprime le nombre de résultats spécifié par l'argument offset.
  2. Récupère et renvoie jusqu'au nombre maximal de résultats spécifié par l'argument limit.

La performance de la boucle évolue donc de manière linéaire avec la somme offset + limit. Si vous connaissez le nombre de résultats à récupérer, vous devez toujours définir une valeur limit explicite.

Cette méthode utilise la prérécupération asynchrone pour améliorer les performances. Par défaut, elle extrait ses résultats du datastore par petits lots, ce qui permet à l'application d'arrêter l'itération et d'éviter de récupérer plus de résultats que nécessaire.

Conseil : Pour récupérer tous les résultats disponibles lorsque leur nombre est inconnu, définissez batch_size sur une valeur élevée, telle que 1000.

Conseil : Si vous n'avez pas besoin de modifier les valeurs d'argument par défaut, il vous suffit d'utiliser l'objet de requête directement comme itérable pour contrôler la boucle. Cela appelle implicitement run() avec les arguments par défaut.

Arguments

read_policy
Règles de lecture indiquant le niveau de cohérence des données souhaité :
STRONG_CONSISTENCY
Garantit l'obtention des résultats les plus récents, mais se limite à un seul groupe d'entités.
EVENTUAL_CONSISTENCY
Peut s'étendre à plusieurs groupes d'entités, mais peut parfois renvoyer des résultats obsolètes. En général, les requêtes cohérentes à terme s'exécutent plus rapidement que les requêtes fortement cohérentes, mais cela n'est pas garanti.

Remarque : Les requêtes globales (non ascendantes) ignorent cet argument.

deadline
Délai d'attente maximal exprimé en secondes au terme duquel Datastore renvoie un résultat avant d'abandonner en signalant une erreur. Accepte un entier ou une valeur à virgule flottante. Ne peut pas être défini sur une valeur supérieure à la valeur par défaut (60 secondes). Toutefois, il est possible de définir une durée plus courte pour garantir qu'une opération particulière échoue rapidement (par exemple, pour renvoyer une réponse plus rapide à l'utilisateur, retenter une opération, lancer une autre opération ou ajouter l'opération à une file d'attente de tâches).
offset
Nombre de résultats à ignorer avant de renvoyer le premier.
limit
Nombre maximal de résultats sur une page. Si cette valeur est omise ou définie sur None, tous les résultats disponibles sont récupérés par défaut.
batch_size
Nombre de résultats à tenter de récupérer par lot. Si l'argument limit est défini, la valeur par défaut est la limite spécifiée. Sinon, elle correspond à 20.
keys_only
Si la valeur est true, ne renvoie que des clés au lieu d'entités complètes. Les requêtes portant uniquement sur des clés sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.
projection
Liste ou tuple de noms de propriétés à renvoyer. Seules les entités possédant les propriétés spécifiées sont renvoyées. Si cet argument n'est pas spécifié, les entités entières sont renvoyées par défaut. Les requêtes portant sur des projections sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.

Remarque : La spécification de ce paramètre peut modifier les exigences d'index de la requête.

start_cursor
Position du curseur à laquelle lancer la requête.
end_cursor
Position du curseur à laquelle terminer la requête.
get (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Exécute la requête et renvoie le premier résultat, ou None si aucun résultat n'est trouvé.

Arguments

read_policy
Règles de lecture indiquant le niveau de cohérence des données souhaité :
STRONG_CONSISTENCY
Garantit l'obtention des résultats les plus récents, mais se limite à un seul groupe d'entités.
EVENTUAL_CONSISTENCY
Peut s'étendre à plusieurs groupes d'entités, mais peut parfois renvoyer des résultats obsolètes. En général, les requêtes cohérentes à terme s'exécutent plus rapidement que les requêtes fortement cohérentes, mais cela n'est pas garanti.

Remarque : Les requêtes globales (non ascendantes) ignorent cet argument.

deadline
Délai d'attente maximal exprimé en secondes au terme duquel Datastore renvoie un résultat avant d'abandonner en signalant une erreur. Accepte un entier ou une valeur à virgule flottante. Ne peut pas être défini sur une valeur supérieure à la valeur par défaut (60 secondes). Toutefois, il est possible de définir une durée plus courte pour garantir qu'une opération particulière échoue rapidement (par exemple, pour renvoyer une réponse plus rapide à l'utilisateur, retenter une opération, lancer une autre opération ou ajouter l'opération à une file d'attente de tâches).
offset
Nombre de résultats à ignorer avant de renvoyer le premier.
keys_only
Si la valeur est true, ne renvoie que des clés au lieu d'entités complètes. Les requêtes portant uniquement sur des clés sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.
projection
Liste ou tuple de noms de propriétés à renvoyer. Seules les entités possédant les propriétés spécifiées sont renvoyées. Si cet argument n'est pas spécifié, les entités entières sont renvoyées par défaut. Les requêtes portant sur des projections sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.

Remarque : La spécification de ce paramètre peut modifier les exigences d'index de la requête.

start_cursor
Position du curseur à laquelle lancer la requête.
end_cursor
Position du curseur à laquelle terminer la requête.
fetch (limit, read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Exécute la requête et renvoie une liste de résultats (éventuellement vide) :

  1. Récupère et supprime le nombre de résultats spécifié par l'argument offset.
  2. Récupère et renvoie jusqu'au nombre maximal de résultats spécifié par l'argument limit.

La performance de la méthode évolue donc de manière linéaire avec la somme offset + limit.

Remarque : Cette méthode est simplement un wrapper de bas niveau pour la méthode run(). Elle est moins efficace et nécessite davantage de mémoire que l'utilisation directe de run(). Vous devriez rarement avoir besoin d'utiliser la méthode fetch(), qui est principalement fournie pour des raisons pratiques lorsque vous devez récupérer la liste complète des résultats de requête en mémoire.

Conseil : La méthode fetch() est conçue pour ne récupérer que le nombre de résultats spécifié par l'argument limit. Pour récupérer tous les résultats disponibles d'une requête dont le nombre est inconnu, utilisez run() avec une taille de lot volumineuse, telle que run(batch_size=1000), au lieu de fetch().

Arguments

limit
Nombre maximal de résultats sur une page. Si cette valeur est définie sur None, tous les résultats disponibles sont récupérés.
read_policy
Règles de lecture indiquant le niveau de cohérence des données souhaité :
STRONG_CONSISTENCY
Garantit l'obtention des résultats les plus récents, mais se limite à un seul groupe d'entités.
EVENTUAL_CONSISTENCY
Peut s'étendre à plusieurs groupes d'entités, mais peut parfois renvoyer des résultats obsolètes. En général, les requêtes cohérentes à terme s'exécutent plus rapidement que les requêtes fortement cohérentes, mais cela n'est pas garanti.

Remarque : Les requêtes globales (non ascendantes) ignorent cet argument.

deadline
Délai d'attente maximal exprimé en secondes au terme duquel Datastore renvoie un résultat avant d'abandonner en signalant une erreur. Accepte un entier ou une valeur à virgule flottante. Ne peut pas être défini sur une valeur supérieure à la valeur par défaut (60 secondes). Toutefois, il est possible de définir une durée plus courte pour garantir qu'une opération particulière échoue rapidement (par exemple, pour renvoyer une réponse plus rapide à l'utilisateur, retenter une opération, lancer une autre opération ou ajouter l'opération à une file d'attente de tâches).
offset
Nombre de résultats à ignorer avant de renvoyer le premier.
keys_only
Si la valeur est true, ne renvoie que des clés au lieu d'entités complètes. Les requêtes portant uniquement sur des clés sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.
projection
Liste ou tuple de noms de propriétés à renvoyer. Seules les entités possédant les propriétés spécifiées sont renvoyées. Si cet argument n'est pas spécifié, les entités entières sont renvoyées par défaut. Les requêtes portant sur des projections sont plus rapides et moins coûteuses que celles renvoyant des entités complètes.

Remarque : La spécification de ce paramètre peut modifier les exigences d'index de la requête.

start_cursor
Position du curseur à laquelle lancer la requête.
end_cursor
Position du curseur à laquelle terminer la requête.
count (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=1000, start_cursor=None, end_cursor=None)

Renvoie le nombre de résultats correspondant à la requête. Il est plus rapide d'utiliser un facteur constant que de récupérer tous les résultats. Toutefois, le temps d'exécution reste linéaire avec la somme offset + limit. Si vous ne vous attendez pas à obtenir un faible nombre de résultats, il est préférable de spécifier un argument limit. Dans le cas contraire, la méthode continue jusqu'à ce qu'elle ait fini de compter ou expire.

Arguments

read_policy
Règles de lecture indiquant le niveau de cohérence des données souhaité :
STRONG_CONSISTENCY
Garantit l'obtention des résultats les plus récents, mais se limite à un seul groupe d'entités.
EVENTUAL_CONSISTENCY
Peut s'étendre à plusieurs groupes d'entités, mais peut parfois renvoyer des résultats obsolètes. En général, les requêtes cohérentes à terme s'exécutent plus rapidement que les requêtes fortement cohérentes, mais cela n'est pas garanti.

Remarque : Les requêtes globales (non ascendantes) ignorent cet argument.

deadline
Délai d'attente maximal exprimé en secondes au terme duquel Datastore renvoie un résultat avant d'abandonner en signalant une erreur. Accepte un entier ou une valeur à virgule flottante. Ne peut pas être défini sur une valeur supérieure à la valeur par défaut (60 secondes). Toutefois, il est possible de définir une durée plus courte pour garantir qu'une opération particulière échoue rapidement (par exemple, pour renvoyer une réponse plus rapide à l'utilisateur, retenter une opération, lancer une autre opération ou ajouter l'opération à une file d'attente de tâches).
offset
Nombre de résultats à ignorer avant de compter le premier.
limit
Nombre maximal de résultats à compter.
start_cursor
Position du curseur à laquelle lancer la requête.
end_cursor
Position du curseur à laquelle terminer la requête.
index_list ()

Renvoie la liste des index utilisés par une requête exécutée, y compris les index primaires, composites, de types et à propriété unique.

Attention : L'appel de cette méthode sur une requête n'ayant pas encore été exécutée génère une exception AssertionError.

Remarque : Cette fonctionnalité n'est pas entièrement compatible avec le serveur de développement. Lorsqu'elle est utilisée avec ce dernier, vous obtenez une liste vide ou une liste ne contenant qu'un index composite.

Par exemple, le code suivant affiche diverses informations sur les index utilisés par une requête :

# 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 />")

Vous devriez voir un résultat semblable au suivant :

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

Renvoie une chaîne de curseur encodée en base64 qui indique la position suivant le dernier résultat récupéré dans l'ensemble de résultats de la requête. La chaîne de curseur peut être utilisée en toute sécurité dans les paramètres HTTP GET et POST et être stockée dans le datastore ou dans Memcache. Un appel ultérieur de la même requête peut fournir cette chaîne via le paramètre start_cursor ou la méthode with_cursor() pour reprendre la récupération des résultats à partir de cette position.

Attention : L'appel de cette méthode sur une requête n'ayant pas encore été exécutée génère une exception AssertionError.

Remarque : Les requêtes ne sont pas toutes compatibles avec les curseurs. Pour en savoir plus, consultez la page Requêtes Datastore.

with_cursor (start_cursor, end_cursor=None)

Spécifie les positions de départ et (éventuellement) de fin dans l'ensemble de résultats d'une requête depuis lequel vous récupérez des résultats. Les chaînes de curseur indiquant les positions de début et de fin peuvent être obtenues en appelant cursor() après un précédent appel de la requête. La requête en cours doit être identique à l'appel précédent, y compris le genre d'entité, les filtres de propriétés, les filtres d'ancêtre et les ordres de tri.

Arguments

start_cursor
Chaîne de curseur encodée en base64 indiquant où démarrer la requête.
end_cursor
Chaîne de curseur codée en base64 indiquant où terminer la requête.