Entitäten, Attribute und Schlüssel

Hinweis: Entwicklern neuer Anwendungen wird dringend empfohlen, die NDB-Clientbibliothek zu verwenden. Sie bietet im Vergleich zu dieser Clientbibliothek mehrere Vorteile, beispielsweise das automatische Caching von Entitäten über die Memcache API. Wenn Sie derzeit die ältere DB-Clientbibliothek verwenden, lesen Sie die Anleitung zur Migration von DB zu NDB.

Datenobjekte in Cloud Datastore werden als Entitäten bezeichnet. Eine Entität hat ein oder mehrere benannte Attribute, die jeweils einen oder mehrere Werte enthalten können. Entitäten derselben Art müssen nicht dieselben Attribute haben und die Werte der Entitäten für ein bestimmtes Attribut müssen nicht alle denselben Datentyp haben. Falls erforderlich, kann eine Anwendung derartige Einschränkungen in einem eigenen Datenmodell festlegen und durchsetzen.

Cloud Datastore unterstützt eine Vielzahl von Datentypen für Attributwerte. Diese umfassen unter anderem:

  • Ganzzahlen
  • Gleitkommazahlen
  • Strings
  • Datumsangaben
  • Binärdaten

Eine vollständige Liste der Typen finden Sie unter Attribute und Werttypen.

Jede Entität in Cloud Datastore verfügt über einen Schlüssel, der sie eindeutig identifiziert. Der Schlüssel besteht aus den folgenden Komponenten:

  • Namespace der Entität, der die Mehrinstanzenfähigkeit ermöglicht
  • Art der Entität, mit der sie für Cloud Datastore-Abfragen kategorisiert wird
  • Kennzeichnung für die einzelne Entität, entweder
    • ein String mit dem Schlüsselnamen oder
    • eine ganzzahlige numerische ID
  • Optionaler Ancestor-Pfad zur Entität in der Cloud Datastore-Hierarchie

Eine Anwendung kann eine einzelne Entität mithilfe des Entitätsschlüssels aus Cloud Datastore abrufen oder eine bzw. mehrere Entitäten mit einer Abfrage anhand der Schlüssel oder Attributwerte der Entitäten ermitteln.

Das Python App Engine SDK enthält eine Datenmodellierungsbibliothek zur Darstellung von Cloud Datastore-Entitäten als Instanzen von Python-Klassen sowie zum Speichern und Abrufen dieser Instanzen in Cloud Datastore.

Cloud Datastore selbst erzwingt keine Einschränkungen für die Struktur von Entitäten, beispielsweise ob ein bestimmtes Attribut einen Wert eines bestimmten Typs hat. Diese Aufgabe bleibt der Anwendung und der Datenmodellierungsbibliothek überlassen.

Arten und Kennungen

Jede Cloud Datastore-Entität ist von einer bestimmten Art. Diese kategorisiert die Entität für Abfragen. In einer Personalanwendung kann beispielsweise jeder Mitarbeiter eines Unternehmens mit einer Entität der Art Employee dargestellt werden. In der Python Datastore API wird die Art einer Entität durch ihre Modellklasse bestimmt, die Sie in Ihrer Anwendung als abgeleitete Klasse der Klasse db.Model der Datenmodellierungsbibliothek festlegen. Der Name der Modellklasse wird zur Art der zugehörigen Entitäten. Alle Artnamen, die mit zwei Unterstrichen (__) beginnen, sind reserviert und dürfen nicht verwendet werden.

Im folgenden Beispiel wird eine Entität der Art Employee erstellt. Außerdem werden ihre Attributwerte angegeben und die Entität wird in Datastore gespeichert:

import datetime
from google.appengine.ext import db

class Employee(db.Model):
  first_name = db.StringProperty()
  last_name = db.StringProperty()
  hire_date = db.DateProperty()
  attended_hr_training = db.BooleanProperty()

employee = Employee(first_name='Antonio',
                    last_name='Salieri')

employee.hire_date = datetime.datetime.now().date()
employee.attended_hr_training = True

employee.put()

Die Klasse Employee deklariert vier Attribute für das Datenmodell: first_name, last_name, hire_date und attended_hr_training. Die Basisklasse Model gewährleistet, dass die Attribute von Employee-Objekten diesem Modell entsprechen. Beispielsweise würde die Zuweisung eines Stringwerts zum Attribut hire_date zu einem Laufzeitfehler führen, da das Datenmodell für hire_date als db.DateProperty deklariert wurde.

Neben der Art verfügt jede Entität über eine Kennung, die beim Erstellen der Entität zugewiesen wird. Weil sie Teil des Schlüssels der Entität ist, ist die Kennung dauerhaft mit der Entität verknüpft und kann nicht geändert werden. Es gibt zwei Möglichkeiten der Zuweisung:

  • Die Anwendung kann ihren eigenen Schlüsselnamen als String für die Entität angeben.
  • Cloud Datastore kann der Entität automatisch eine ganzzahlige numerische ID zuweisen.

Zum Zuweisen eines Schlüsselnamens zu einer Entität übergeben Sie beim Erstellen der Entität das benannte Argument key_name an den Modellklassenkonstruktor:

# Create an entity with the key Employee:'asalieri'.
employee = Employee(key_name='asalieri')

Wenn Cloud Datastore automatisch eine numerische ID zuweisen soll, lassen Sie das Argument key_name weg:

# Create an entity with a key such as Employee:8261.
employee = Employee()

Kennungen zuweisen

Wenn Sie Cloud Datastore automatisch IDs zuweisen lassen, haben Sie die Wahl zwischen zwei verschiedenen Richtlinien für automatische IDs:

  • Die Richtlinie default generiert eine zufällige Abfolge von bisher nicht verwendeten IDs, die näherungsweise gleichmäßig verteilt sind. Jede ID kann maximal 16 Dezimalstellen enthalten.
  • Die Richtlinie legacy erstellt eine Abfolge nicht aufeinanderfolgender IDs aus kleineren Ganzzahlen.

Wenn Sie die Entitäts-IDs für den Nutzer anzeigen möchten und/oder deren Reihenfolge wichtig ist, ist eine manuelle Zuordnung die beste Lösung.

Cloud Datastore generiert eine zufällige Abfolge von bisher nicht verwendeten IDs, die näherungsweise gleichmäßig verteilt sind. Jede ID kann maximal 16 Dezimalstellen enthalten.

Vom System zugeordnete ID-Werte sind für die Entitätengruppe garantiert eindeutig. Wenn Sie eine Entität aus einer Entitätengruppe oder einem Namespace in eine andere Entitätengruppe oder einen anderen Namespace kopieren und den ID-Teil des Schlüssels beibehalten möchten, achten Sie darauf, dass Sie die ID zuerst zuordnen, damit Datastore sie nicht für eine zukünftige Zuweisung auswählt.

Ancestor-Pfade

Entitäten in Cloud Datastore sind hierarchisch organisiert, ähnlich der Verzeichnisstruktur eines Dateisystems. Wenn Sie eine Entität erstellen, können Sie optional eine weitere Entität als übergeordnetes Element angeben. Die neue Entität ist dann ein untergeordnetes Element der übergeordneten Entität. Im Gegensatz zu einem Dateisystem muss die übergeordnete Entität nicht tatsächlich vorhanden sein. Eine Entität ohne übergeordnetes Element wird als Stammentität bezeichnet. Die Verknüpfung zwischen einer Entität und ihrer übergeordneten Entität ist dauerhaft und kann nicht geändert werden, nachdem die Entität erstellt wurde. Cloud Datastore weist zwei Entitäten mit derselben übergeordneten Entität oder zwei Stammentitäten (Entitäten ohne übergeordnete Entität) niemals dieselbe numerische ID zu.

Alle übergeordneten Elemente einer Entität werden als ihre Ancestors bezeichnet und alle untergeordneten Entitäten sind ihre Nachfolger. Eine Stammentität und alle ihre Nachfolger gehören zu derselben Entitätengruppe. Die Abfolge der Entitäten, von einer Stammentität über die untergeordneten Elemente bis zu einer bestimmten Entität, bildet den Ancestor-Pfad. Der vollständige Schlüssel, der die Entität identifiziert, besteht aus einer Abfolge von Art/Kennungs-Paaren, die den Ancestor-Pfad angeben und mit dem Paar der Entität selbst enden:

[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]

Bei einer Stammentität ist der Ancestor-Pfad leer und der Schlüssel besteht ausschließlich aus der eigenen Art und der eigenen Kennung der Entität:

[Person:GreatGrandpa]

Dieses Konzept wird anhand des folgenden Diagramms veranschaulicht:

Zeigt die Beziehung der Stammentität zu den untergeordneten Entitäten in der Entitätengruppe an

Zur Angabe der übergeordneten Entität einer Entität verwenden Sie beim Erstellen der untergeordneten Entität das Argument parent für den Modellklassenkonstruktor. Der Wert dieses Arguments kann die übergeordnete Entität selbst oder ihr Schlüssel sein. Der Schlüssel lässt sich durch Aufrufen der Methode key() der übergeordneten Entität ermitteln. Im folgenden Beispiel wird eine Entität der Art Address erstellt. Außerdem werden zwei Möglichkeiten zum Angeben einer Entität der Art Employee als deren übergeordnete Entität gezeigt:

# Create Employee entity
employee = Employee()
employee.put()

# Set Employee as Address entity's parent directly...
address = Address(parent=employee)

# ...or using its key
e_key = employee.key()
address = Address(parent=e_key)

# Save Address entity to datastore
address.put()

Transaktionen und Entitätengruppen

Jeder Vorgang zum Erstellen, Aktualisieren und Löschen einer Entität findet im Rahmen einer Transaktion statt. Eine einzelne Transaktion kann eine beliebige Anzahl solcher Vorgänge umfassen. Zur Wahrung der Datenkonsistenz sorgt die Transaktion dafür, dass alle enthaltenen Vorgänge auf Cloud Datastore als Einheit angewendet werden oder keiner der Vorgänge angewendet wird, falls einer der Vorgänge fehlschlägt. Darüber hinaus greifen alle strikt konsistenten Lesevorgänge (Ancestor-Abfragen oder -Abrufe) innerhalb derselben Transaktion auf einen konsistenten Snapshot der Daten zurück.

Wie oben bereits erwähnt besteht eine Entitätengruppe aus einer Reihe von Entitäten, die über einen Ancestor-Pfad mit einem gemeinsamen Stammelement verbunden sind. Die Anordnung von Daten in Entitätengruppen kann einschränken, welche Transaktionen ausgeführt werden können:

  • Alle Daten, auf die eine Transaktion zugreift, müssen in maximal 25 Entitätengruppen enthalten sein.
  • Wenn Sie Abfragen innerhalb einer Transaktion verwenden möchten, müssen die Daten so in Entitätengruppen angeordnet werden, dass Sie Ancestor-Filter angeben können, die mit den richtigen Daten übereinstimmen.
  • Es gibt einen Schreibdurchsatzgrenzwert von ca. einer Transaktion pro Sekunde innerhalb einer einzelnen Entitätengruppe. Diese Begrenzung ist vorhanden, weil Cloud Datastore eine synchrone Replikation ohne Master jeder Entitätengruppe über einen breiten geografischen Bereich hinweg durchführt, um hohe Verlässlichkeit und Fehlertoleranz zu ermöglichen.

In vielen Anwendungen kann es akzeptabel sein, für den Abruf einer breiten Ansicht nicht zusammengehöriger Daten Eventual Consistency zu verwenden, also eine entitätsgruppenübergreifende Nicht-Ancestor-Abfrage, die gelegentlich etwas veraltete Daten zurückgeben kann. Anschließend wird dann strikte Konsistenz (eine Ancestor-Abfrage oder ein get einer einzelnen Entität) verwendet, um eine einzelne Gruppe von eng zusammengehörigen Daten anzuzeigen oder zu bearbeiten. In derartigen Anwendungen ist es oft ein guter Ansatz, für jeden Satz eng zusammengehöriger Daten jeweils eine separate Entitätengruppe zu verwenden. Weitere Informationen finden Sie unter Für strikte Konsistenz strukturieren.

Attribute und Werttypen

Die mit einer Entität verknüpften Datenwerte bestehen aus einem oder mehreren Attributen. Jedes Attribut hat einen Namen und einen oder mehrere Werte. Ein Attribut kann Werte mit mehr als einem Typ haben und zwei Entitäten können Werte unterschiedlichen Typs für dasselbe Attribut haben. Attribute können indexiert oder nicht indexiert sein. Abfragen, die nach einem Attribut A sortieren oder filtern, ignorieren Entitäten, bei denen A nicht indexiert ist. Eine Entität kann höchstens 20.000 indexierte Attribute haben.

Die folgenden Werttypen werden unterstützt:

Werttyp Python-Typ(en) Sortierfolge Hinweise
Ganzzahl int
long
Numerisch 64-Bit-Ganzzahl, signiert
Gleitkommazahl float Numerisch 64-Bit mit doppelter Genauigkeit,
IEEE 754
Boolesch bool False<True
Textstring (kurz) str
unicode
Unicode
(str als ASCII behandelt)
Bis zu 1.500 Byte
Textstring (lang) db.Text Bis zu 1 Megabyte

Nicht indexiert
Bytestring (kurz) db.ByteString Bytereihenfolge Bis zu 1.500 Byte
Bytestring (lang) db.Blob Bis zu 1 Megabyte

Nicht indexiert
Datum und Uhrzeit datetime.date
datetime.time
datetime.datetime
Chronologisch
Geografischer Punkt db.GeoPt Nach Breitengrad,
dann Längengrad
Postanschrift db.PostalAddress Unicode
Telefonnummer db.PhoneNumber Unicode
E-Mail-Adresse db.Email Unicode
Nutzer eines Google-Kontos users.User E-Mail-Adresse
in Unicode-Reihenfolge
Instant-Messaging-Handle db.IM Unicode
Link db.Link Unicode
Kategorie db.Category Unicode
Bewertung db.Rating Numerisch
Cloud Datastore-Schlüssel db.Key Nach Pfadelementen
(Art, Kennung,
Art, Kennung...)
Blobstore-Schlüssel blobstore.BlobKey Bytereihenfolge
Null NoneType

Wichtig: Es wird dringend empfohlen, kein UserProperty-Attribut zu speichern, da dieses Attribut die E-Mail-Adresse und die eindeutige ID des Nutzers enthält. Wenn ein Nutzer seine E-Mail-Adresse ändert und Sie seinen alten gespeicherten User mit dem neuen User vergleichen, stimmen die Werte nicht überein.

Für Textstrings und nicht codierte Binärdaten (Bytestrings) unterstützt Cloud Datastore zwei Werttypen:

  • Kurze Strings (bis zu 1.500 Byte) werden indexiert und können in Filterbedingungen der Abfrage und in Sortierfolgen verwendet werden.
  • Lange Strings (bis zu 1 Megabyte) werden nicht indexiert und können nicht in Abfragefiltern und Sortierfolgen verwendet werden.
Hinweis: Der lange Bytestringtyp hat in der Cloud Datastore API die Bezeichnung Blob. Dieser ist nicht mit den Blobs identisch, die in der Blobstore API verwendet werden.

Wenn eine Abfrage ein Attribut mit Werten gemischter Typen umfasst, verwendet Cloud Datastore eine deterministische Sortierung auf Basis der internen Darstellungen:

  1. Nullwerte
  2. Festkommazahlen
    • Ganzzahlen
    • Datums- und Uhrzeitwerte
    • Bewertungen
  3. Boolesche Werte
  4. Bytesequenzen
    • Bytestring
    • Unicode-String
    • Blobstore-Schlüssel
  5. Gleitkommazahlen
  6. Geografische Punkte
  7. Nutzer von Google-Konten
  8. Cloud Datastore-Schlüssel

Da lange Textstrings und lange Bytestrings nicht indexiert werden, ist keine Reihenfolge definiert.

Mit Entitäten arbeiten

Anwendungen können Entitäten mit der Cloud Datastore API erstellen, abrufen, aktualisieren und löschen. Wenn die Anwendung den vollständigen Schlüssel für eine Entität kennt (oder ihn aus dem übergeordneten Schlüssel, der Art und der Kennung ableiten kann), kann sie mit dem Schlüssel direkt mit der Entität arbeiten. Eine Anwendung kann den Schlüssel einer Entität auch als Ergebnis einer Cloud Datastore-Abfrage erhalten. Weitere Informationen finden Sie auf der Seite Datenspeicherabfragen.

Entität erstellen

Zum Erstellen einer neuen Entität in Python müssen Sie eine Instanz einer Modellklasse anlegen, bei Bedarf deren Attribute angeben und ihre Methode put() aufrufen, um sie in Datastore zu speichern. Wenn Sie den Schlüsselnamen der Entität angeben möchten, übergeben Sie das Argument "key_name" an den Konstruktor:

employee = Employee(key_name='asalieri',
                    first_name='Antonio',
                    last_name='Salieri')

employee.hire_date = datetime.datetime.now().date()
employee.attended_hr_training = True

employee.put()

Wenn Sie keinen Schlüsselnamen angeben, generiert Cloud Datastore automatisch eine numerische ID für den Schlüssel der Entität:

employee = Employee(first_name='Antonio',
                    last_name='Salieri')

employee.hire_date = datetime.datetime.now().date()
employee.attended_hr_training = True

employee.put()

Entität abrufen

Zum Abrufen einer Entität, die durch einen bestimmten Schlüssel identifiziert wird, übergeben Sie das Objekt Key als Argument an die Funktion db.get(). Das Objekt Key kann mithilfe der Klassenmethode Key.from_path() generiert werden. Der vollständige Pfad ist eine Abfolge von Entitäten im Ancestor-Pfad, wobei jede Entität durch ihre Art (ein String) gefolgt von ihrer Kennung (Schlüsselname oder numerische ID) dargestellt wird:

address_k = db.Key.from_path('Employee', 'asalieri', 'Address', 1)
address = db.get(address_k)

db.get() gibt eine Instanz der entsprechenden Modellklasse zurück. Bestätigen Sie, dass Sie die Modellklasse für die abzurufende Entität importiert haben.

Entität aktualisieren

Wenn Sie eine vorhandene Entität aktualisieren möchten, ändern Sie die Attribute des Objekts und rufen dann die zugehörige Methode put() auf. Die bestehende Entität wird mit den Objektdaten überschrieben. Bei jedem Aufruf von put() wird das ganze Objekt an Cloud Datastore gesendet.

Zum Löschen eines Attributs löschen Sie das Attribut aus dem Python-Objekt:

del address.postal_code

Speichern Sie dann das Objekt.

Entität löschen

Sie können eine Entität unter Angabe ihres Schlüssels mit der Funktion db.delete() löschen:

address_k = db.Key.from_path('Employee', 'asalieri', 'Address', 1)
db.delete(address_k)

Es besteht auch die Möglichkeit, dafür die Methode delete() der Entität aufzurufen:

employee_k = db.Key.from_path('Employee', 'asalieri')
employee = db.get(employee_k)

# ...

employee.delete()

Batchvorgänge

Für die Funktionen db.put(), db.get() und db.delete() und ihre asynchronen Gegenstücke db.put_async(), db.get_async() und db.delete_async() können Listenargumente angegeben werden, um einen Vorgang für mehrere Entitäten in einem einzigen Cloud Datastore-Aufruf auszuführen:

# A batch put.
db.put([e1, e2, e3])

# A batch get.
entities = db.get([k1, k2, k3])

# A batch delete.
db.delete([k1, k2, k3])

Batch-Vorgänge ändern nichts an Ihren Kosten. Jeder Schlüssel in einem Batchvorgang wird unabhängig davon in Rechnung gestellt, ob der Schlüssel vorhanden ist oder nicht. Die Größe der Entitäten in einem Vorgang wirkt sich nicht auf die Kosten aus.

Entitäten im Bulk löschen

Wenn Sie Entitäten in großen Mengen löschen müssen, empfehlen wir die Verwendung von Cloud Dataflow zum Löschen von Entitäten im Bulk.

Leere Liste verwenden

Für die NDB-Schnittstelle hat Cloud Datastore in der Vergangenheit eine leere Liste als ausgelassenes Attribut für statische und dynamische Attribute geschrieben. Zur Aufrechterhaltung der Abwärtskompatibilität bleibt dies das Standardverhalten. Wenn Sie dieses Verhalten global oder pro ListProperty-Basis überschreiben möchten, legen Sie für das Argument write_empty_list in der Attributklasse den Wert true fest. Die leere Liste wird dann in Cloud Datastore geschrieben und kann als leere Liste gelesen werden.

Für die DB-Schnittstelle waren Schreibvorgänge mit leeren Listen in der Vergangenheit bei dynamischen Attributen in keinem Fall zulässig. Wenn Sie solche Vorgänge ausführten, kam es zu einem Fehler. Dies bedeutet, dass kein Standardverhalten zwecks Abwärtskompatibilität für dynamische DB-Attribute beibehalten werden muss und Sie die leere Liste im dynamischen Modell ohne Änderungen einfach schreiben und lesen können.

Bei statischen DB-Attributen wurde die leere Liste jedoch als ausgelassenes Attribut geschrieben. Dieses Verhalten wird aus Gründen der Abwärtskompatibilität standardmäßig beibehalten. Wenn Sie leere Listen für statische DB-Attribute aktivieren möchten, legen Sie für das Argument write_empty_list in der Attributklasse den Wert true fest. Die leere Liste wird dann in Cloud Datastore geschrieben.

Hat Ihnen diese Seite weitergeholfen? Teilen Sie uns Ihr Feedback mit:

Feedback geben zu...

App Engine-Standardumgebung für Python 2