Entitätsschlüssel erstellen und verwenden

Jede Entität wird durch einen Schlüssel identifiziert, der innerhalb der Datastore-Instanz der Anwendung eindeutig ist und aus folgenden Elementen besteht:

  • Art: Die Art ist normalerweise der Name der Modellklasse, zu der die Entität gehört. Sie können dies jedoch in einen anderen String ändern, indem Sie die Klassenmethode _get_kind() überschreiben.
  • Kennung: Sie geben Ihren eigenen Schlüsselnamen als Kennung an oder lassen Cloud Datastore automatisch eine ganzzahlige numerische ID generieren.

Eigenen Schlüsselnamen angeben

Im folgenden Beispiel wird implizit ein Schlüssel mit einer Stringkennung unter Verwendung des benannten Parameters id erstellt:

account = Account(
    username='Sandy', userid=1234, email='sandy@example.com',
    id='sandy@example.com')

return account.key.id()  # returns 'sandy@example.com'

Sie könnten alternativ den Schlüsselnamen direkt festlegen:

account.key = ndb.Key('Account', 'sandy@example.com')

# You can also use the model class object itself, rather than its name,
# to specify the entity's kind:
account.key = ndb.Key(Account, 'sandy@example.com')

ID für den Schlüssel in Datastore generieren lassen

Dieser Code zeigt, wie Sie eine automatisch generierte ID als Schlüssel verwenden können:

# note: no id kwarg
account = Account(username='Sandy', userid=1234, email='sandy@example.com')
account.put()
# account.key will now have a key of the form: ndb.Key(Account, 71321839)
# where the value 71321839 was generated by Datastore for us.

Ancestor-Pfad im Schlüssel verwenden

Die Abfolge der Entitäten von einer Stammentität über die übergeordneten und untergeordneten Elemente bis zu einer bestimmten Entität bildet den Ancestor-Pfad. Die übergeordnete Entität einer Entität, die übergeordnete Entität der übergeordneten Entität und so weiter sind deren Ancestors. Die Entitäten im Datastore bilden einen hierarchischen Schlüsselbereich, der der hierarchischen Verzeichnisstruktur eines Dateisystems ähnelt.

Der vollständige Schlüssel, der die Entität identifiziert, besteht aus einer Abfolge von Art/Kennungs-Paaren, die deren Ancestor-Pfad angeben und mit den Paaren der Entität selbst enden: Die Konstruktormethode für die Klasse Key akzeptiert eine Folge aus Arten und Kennungen und gibt ein Objekt zurück, das den Schlüssel für die entsprechende Entität darstellt.

Das folgende Beispiel zeigt einen Blogdienst, der Nachrichten nach Revision speichert. Nachrichten sind unter Konten organisiert und Revisionen unter Nachrichten.

class Revision(ndb.Model):
    message_text = ndb.StringProperty()
...
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '2')
ndb.Key('Account', 'larry@example.com', 'Message', 456, 'Revision', '1')
ndb.Key('Account', 'larry@example.com', 'Message', 789, 'Revision', '2')

Im Beispiel sind ('Account', 'sandy@example.com'), ('Message', 123) und ('Revision', '1') Beispiele für Art/Kennungs-Paare.

Beachten Sie, dass Message keine Modellklasse ist. Sie dient nur zur Gruppierung von Revisionen und nicht zum Speichern von Daten.

Wie im Beispielcode gezeigt, wird die Art der Entität durch das letzte Art/Namens-Paar in der Liste angegeben: ndb.Key('Revision', '1').

Benannte Parameter verwenden

Sie können den benannten Parameter parent verwenden, um eine Entität direkt im Ancestor-Pfad anzugeben. Alle folgenden Notationen stellen denselben Schlüssel dar:

ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')

ndb.Key('Revision', '1', parent=ndb.Key(
    'Account', 'sandy@example.com', 'Message', 123))

ndb.Key('Revision', '1', parent=ndb.Key(
    'Message', 123, parent=ndb.Key('Account', 'sandy@example.com')))

Stammentität angeben

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:

sandy_key = ndb.Key(Account, 'sandy@example.com')

Entität mit Ancestors angeben

So fügen Sie eine neue Nachricht mit übergeordneten Schlüsseln ein:

account_key = ndb.Key(Account, 'sandy@example.com')

# Ask Datastore to allocate an ID.
new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]

# Datastore returns us an integer ID that we can use to create the message
# key
message_key = ndb.Key('Message', new_id, parent=account_key)

# Now we can put the message into Datastore
initial_revision = Revision(
    message_text='Hello', id='1', parent=message_key)
initial_revision.put()

Für Schlüssel, die mit einem übergeordneten Element erstellt wurden, gibt die Methode parent() einen Schlüssel zurück, der die übergeordnete Entität darstellt:

message_key = initial_revision.key.parent()

Numerische Schlüssel-IDs verwenden

Sie können eine Entität erstellen, ohne eine ID anzugeben. In diesem Fall generiert der Datenspeicher automatisch eine numerische ID. Wenn Sie einige IDs selbst angeben und andere IDs von Datastore automatisch generieren lassen, ist die Anforderung der Eindeutigkeit bei den Schlüsseln möglicherweise nicht erfüllt. Reservieren Sie einen Nummernbereich, den Sie für die Auswahl von IDs nutzen können, oder verwenden Sie String-IDs, um dieses Problem ganz zu vermeiden.

Verwenden Sie die Klassenmethode allocate_ids() der Modellklasse, um einen ID-Bereich zu reservieren:

  • eine bestimmte Anzahl von IDs zuordnen
  • alle IDs bis zu einem bestimmten Maximalwert zuordnen

IDs zuordnen

So weisen Sie 100 IDs für eine bestimmte Modellklasse MyModel zu:

first, last = MyModel.allocate_ids(100)

So weisen Sie 100 IDs für Entitäten mit dem übergeordneten Schlüssel p zu:

first, last = MyModel.allocate_ids(100, parent=p)

Die zurückgegebenen Werte first und last sind jeweils die ersten und letzten zugewiesenen IDs (einschließlich). Damit können Sie Schlüssel so konstruieren:

keys = [ndb.Key(MyModel, id) for id in range(first, last+1)]

Diese Schlüssel werden garantiert nicht vom internen ID-Generator des Datenspeichers oder zukünftigen Aufrufen an den internen ID-Generator zurückgegeben. Die Methode allocate_ids() prüft jedoch nicht, ob die zurückgegebenen IDs im Datenspeicher vorhanden sind. Sie interagiert nur mit dem ID-Generator.

So weisen Sie alle IDs bis zu einem bestimmten Maximalwert zu:

first, last = MyModel.allocate_ids(max=N)

Dieses Formular sorgt dafür, dass alle IDs kleiner oder gleich N als zugewiesen gelten. Die Rückgabewerte first und last geben den Bereich der von diesem Vorgang reservierten IDs an. Es ist kein Fehler, die bereits zugewiesenen IDs zu reservieren. In diesem Fall gibt first die erste ID an, die noch nicht zugewiesen wurde, und last die letzte zugewiesene ID.