GQL-Referenz für Python NDB/DB

GQL ist eine SQL-ähnliche Sprache zum Abrufen von Entitäten und Schlüsseln. Die Syntax für GQL-Abfragen ähnelt der von SQL. Diese Seite enthält eine Referenz zur Verwendung von GQL mit den Python NDB- und DB-Clientbibliotheken.

GQL entspricht ungefähr SQL: Sie können sich einen GQL-kind als SQL-Tabelle, eine GQL-entity als SQL-Zeile und eine GQL-property als SQL-Spalte vorstellen. Eine SQL-Zeilen-/Spaltensuche ist jedoch ein einzelner Wert, während in GQL ein Attributwert eine Liste sein kann.

GQL-Versionen

Sie benötigen unterschiedliche Versionen von GQL, je nachdem, wo Sie Abfragen ausführen. Es gibt zwei GQL-Referenzen:

  • GQL-Referenz für Python NDB/DB für die GQL-Grammatik, die in den NDB- und DB-Clientbibliotheken verwendet wird (verwenden Sie die Referenz auf dieser Seite)

  • GQL-Referenz für die GQL-Grammatik, die in der aktuellen Datastore API und auf der Seite "Datastore" in der Google Cloud Console verwendet wird

Syntax

Die GQL-Syntax für Python NDB/DB kann so zusammengefasst werden:

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

Wie bei SQL wird bei GQL-Suchbegriffen die Groß- und Kleinschreibung nicht berücksichtigt. Bei Art- und Attribut-Namen wird zwischen Groß- und Kleinschreibung unterschieden.

GQL unterstützt nur SELECT-Anweisungen.

Eine GQL-Abfrage gibt null oder mehr ganze Entitäten, projizierte Entitäten oder Schlüssel der angeforderten Art zurück. Jede GQL-Abfrage beginnt immer mit SELECT *, SELECT __key__ oder SELECT <property list>, wobei property eine durch Kommas getrennte Liste einer oder mehrerer Entitätseigenschaften ist, die von der Abfrage zurückgegeben werden sollen. Eine GQL-Abfrage kann keine SQL-ähnliche "Join"-Abfrage ausführen.

Tipp: SELECT __key__ or SELECT <property list> -Abfragen sind schneller und benötigen weniger CPU-Zeit als SELECT *-Abfragen.

Die optionale Klausel DISTINCT(experimentell) gibt an, dass nur vollständig eindeutige Ergebnisse in einem Ergebnissatz zurückgegeben werden. So wird nur das erste Ergebnis für Entitäten zurückgegeben, die für die projizierten Attribute dieselben Werte haben.

Die optionale FROM-Klausel begrenzt den Ergebnissatz auf die Entitäten der angegebenen Art. Eine Abfrage ohne FROM-Klausel wird als typlose Abfrage bezeichnet und kann nur eine WHERE-Klausel enthalten, die das Attribut __key__ angibt.

Die optionale WHERE-Klausel begrenzt den Ergebnissatz auf die Entitäten, die eine oder mehrere Bedingungen erfüllen. Bei jeder Bedingung wird ein Attribut der Entität über einen Vergleichsoperator mit einem Wert verglichen. Wenn mehrere Bedingungen mit dem Suchbegriff AND verknüpft sind, muss eine Entität alle Bedingungen erfüllen, um von der Abfrage zurückgegeben zu werden. In GQL gibt es keinen OR-Operator. Es ist jedoch ein IN-Operator verfügbar, der eine eingeschränkte Form von OR bietet.

Der Operator IN vergleicht den Wert eines Attributs mit jedem Element in einer Liste. Der Operator IN entspricht vielen =-Abfragen (eine für jeden Wert), die über OR verknüpft sind. Eine Entität, deren Wert für das gegebene Attribut mit einem der Werte in der Liste übereinstimmt, kann für die Abfrage zurückgegeben werden.

Hinweis: Bei den Operatoren IN und != werden im Hintergrund mehrere Abfragen verwendet. Beispielsweise führt der Operator IN für jedes Element in der Liste eine separate Abfrage mit dem zugrunde liegenden Datenspeicher aus. Die zurückgegebenen Entitäten sind ein Ergebnis des Kreuzprodukts aller zugrunde liegenden Datenspeicherabfragen und werden dedupliziert. Pro einzelner GQL-Abfrage sind bis zu 30 Datenspeicherabfragen zulässig.

Mit Bedingungen kann auch geprüft werden, ob eine Entität eine bestimmte Entität als übergeordnetes Element aufweist. Dabei wird der ANCESTOR IS-Operator verwendet. Der Wert ist eine Modellinstanz oder ein Schlüssel für die Ancestor-Entität. Weitere Informationen zu Ancestors finden Sie unter Schlüssel und Entitätsgruppen.

Bei der linken Seite eines Vergleichs handelt es sich immer um einen Attributsnamen. Ein typischer Attributsname besteht aus alphanumerischen Zeichen, die optional mit Unterstrichen und Punkten kombiniert sein können. Mit anderen Worten, sie entsprechen dem regulären Ausdruck [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*.

Achtung: Attributsnamen, die andere druckbare Zeichen enthalten, müssen in Anführungszeichen gesetzt werden, Beispiel: "first-name" Leerzeichen oder nicht druckbare Zeichen werden in Attributsnamen nicht unterstützt.

Die rechte Seite eines Vergleichs kann (abhängig vom Datentyp des Attributs) so aussehen:

  • Ein str-Literal als String in einfachen Anführungszeichen. Zeichen mit einfachen Anführungszeichen im String müssen mit Escapezeichen ('') versehen werden. Beispiel: 'Joe''s Diner'
  • Ein Ganzzahl- oder Gleitkommaliteral. Beispiel: 42.7
  • Ein boolesches Literal wie TRUE oder FALSE
  • Das NULL-Literal, das für den Nullwert steht (in Python None)
  • Ein Literal mit Datum und Uhrzeit, ein Literal mit Datum oder ein Literal mit Uhrzeit, entweder mit numerischen Werten oder mit einer Darstellung als String in den folgenden Formen:
    • 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')
  • Ein Entitätsschlüsselliteral mit entweder einem stringcodierten Schlüssel oder einem vollständigen Pfad mit Arten und Schlüsselnamen/IDs:

    • KEY('encoded key')
    • KEY('kind', 'name'/ID [, 'kind', 'name'/ID...])
  • Ein Nutzerobjektliteral mit der E-Mail-Adresse des Nutzers:
    USER('email-address')
  • Ein GeoPt-Literal mit Längen- und Breitengrad als Gleitkommawert:
    GEOPT(lat, long)
  • Ein gebundener Parameterwert. Im Abfragestring werden Positionsparameter mit der Nummer referenziert: title = :1. Suchbegriffparameter werden mit dem Namen referenziert: title = :mytitle

Hinweis: Bedingungen der Form property = NULL prüfen, ob im Datenspeicher explizit ein Nullwert für dieses Attribut gespeichert ist. Dies entspricht nicht der Prüfung, ob bei der Entität kein Wert für das Attribut vorliegt! Bei Datenspeicherabfragen, mit denen auf ein Attribut verwiesen wird, werden nie Entitäten zurückgegeben, die für dieses Attribut keinen Wert haben.

Gebundene Parameter können als Positions- oder Suchbegriffargumente verknüpft und an den GqlQuery-Konstruktor oder die Methode "gql()" einer Modellklasse weitergegeben werden. Attributdatentypen, die keine entsprechende Wertliteralsyntax haben, müssen mit Parameterbindung einschließlich des Listendatentyps angegeben werden. Parameterbindungen können während der Lebensdauer der GqlQuery-Instanz über die Methode "bind()" mit neuen Werten neu verknüpft werden, z. B. um eine Abfrage effizient wiederzuverwenden.

Die optionale ORDER BY-Klausel gibt an, dass die Ergebnisse nach den angegebenen Eigenschaften sortiert werden sollen, entweder in aufsteigender (ASC) oder absteigender (DESC) Reihenfolge. Mit der ORDER BY-Klausel können mehrere Sortierreihenfolgen als durch Trennzeichen getrennte Liste angegeben werden, die von links nach rechts berücksichtigt wird. Wenn keine Richtung angegeben ist, wird standardmäßig nach der ASC-Reihenfolge sortiert. Ohne Angabe einer ORDER BY-Klausel ist die Reihenfolge der Ergebnisse nicht definiert und kann sich mit der Zeit ändern.

Durch Angabe einer optionalen LIMIT-Klausel werden von der Anfrage nach den ersten <count>-Entitäten keine Ergebnisse mehr zurückgegeben. Die LIMIT-Klausel kann auch einen <offset> enthalten, um die angegebene Anzahl von Ergebnissen zu überspringen und das erste folgende Ergebnis zurückzugeben. Bei der optionalen OFFSET-Klausel kann <offset> angegeben werden, wenn keine LIMIT-Klausel vorhanden ist.

Hinweis: Wie auch der Parameter offset für die Methode fetch() verringert ein OFFSET in einem GQL-Abfragestring nicht die Anzahl der Entitäten, die vom Datenspeicher abgerufen werden. Diese Angabe wirkt sich nur darauf aus, wie viele Ergebnisse von der fetch()-Methode zurückgegeben werden. Die Leistungsmerkmale einer Abfrage mit einem Offset verhalten sich linear zur Offset-Größe plus der Limit-Größe.

Informationen zum Ausführen von GQL-Abfragen, zu Bindungsparametern und zum Zugriff auf Ergebnisse finden Sie in der Klasse GqlQuery und der Klassenmethode Model.gql().

Beispiele

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

Verwenden Sie diese Abfrage, um alle Entitäten der Art Person zu finden, deren Alter zwischen 18 und 35 liegt (d. h. sowohl Charlies als auch Edna):

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

Verwenden Sie diese Abfrage, um die drei Entitäten der Art Person mit dem höchsten Alter zu finden (d. h. Amy, Betty und Charlie):

SELECT * FROM Person ORDER BY age DESC LIMIT 3

Verwenden Sie diese Abfrage, um alle Entitäten der Art Person zu finden, deren Name "Betty" oder "Charlie" lautet:

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

Verwenden Sie diese Abfrage, um nur die name-Werte für jede Person zurückzugeben:

SELECT name FROM Person

Verwenden Sie diese Abfrage, um nur die name-Werte für jede Person zurückzugeben, sortiert nach age:

SELECT name FROM Person ORDER BY age

Verwenden Sie diese Abfrage, um die Schlüssel der Entitäten der Art Person zu finden, die ein Alter von None haben (d. h. KEY('Person', 'georgemichael')):

SELECT __key__ FROM Person WHERE age = NULL

Verwenden Sie diese Abfrage, um unabhängig vom Typ alle Entitäten zu finden, die sich in der Entitätsgruppe von Amy befinden (d. h. Amy und Fred):

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

Sie können __key__ auf der linken Seite einer Bedingung verwenden, um nach dem Schlüssel zu filtern. Zum Beispiel können Sie Folgendes verwenden, um alle Entitäten Person abzurufen, deren Nutzername mit "a" beginnt.

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

Hinweis: Wenn Sie eine Abfrage erstellen, die auf eine Gleichheit in __key__ überprüft, sollten Sie stattdessen get() verwenden, um die Entität direkt abzurufen.