Creazione e utilizzo delle chiavi di entità

Ogni entità è identificata da una chiave univoca all'interno dell'istanza Datastore dell'applicazione ed è composta da:

  • Tipo. Il tipo è in genere il nome della classe del modello a cui appartiene l'entità, ma puoi modificarlo in un'altra stringa sostituendo il metodo di classe _get_kind().
  • Identificatore. Specifica il tuo nome chiave come identificatore o consenti a Datastore di generare automaticamente un ID numerico intero.

Specificare il proprio nome chiave

L'esempio seguente crea implicitamente una chiave con un identificatore stringa utilizzando il parametro denominato id:

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

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

In alternativa, puoi impostare direttamente il nome chiave:

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

Consentire a Datastore di generare un ID da utilizzare per la chiave

Questo codice mostra come utilizzare un ID generato automaticamente come chiave:

# 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.

Utilizzare il percorso predecessore nella chiave

La sequenza di entità che inizia con entità base e procede da entità principale a entità secondaria, fino a un'entità specifica, costituisce il percorso predecessore di quell'entità. Un'entità, la sua entità principale, l'entità principale dell'entità principale e così via in modo ricorsivo sono i predecessori dell'entità. Le entità in Datastore formano uno spazio chiave gerarchico simile alla struttura di directory gerarchica di un file system.

La chiave completa che identifica un'entità è costituita da una sequenza di coppie tipo-identificatore che specificano il percorso predecessore e terminano con quelle dell'entità stessa. Il metodo costruttore per la classe Key accetta una sequenza di tipi e identificatori e restituisce un oggetto che rappresenta la chiave per l'entità corrispondente.

L'esempio seguente mostra un servizio di blogging che archivia i messaggi per revisione. I messaggi sono organizzati in account e le revisioni sono sotto i messaggi.

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

Nell'esempio, ('Account', 'sandy@example.com'), ('Message', 123) e ('Revision', '1') sono tutti esempi di coppie tipo-identificatore.

Tieni presente che Message non è una classe di modello; viene utilizzata solo come modo per raggruppare le revisioni, non per archiviare i dati.

Come mostrato nel codice campione, il tipo dell'entità è designato dall'ultima coppia tipo-nome nell'elenco: ndb.Key('Revision', '1').

Utilizzare i parametri denominati

Puoi utilizzare il parametro denominato parent per designare direttamente qualsiasi entità nel percorso predecessore. Tutte le seguenti notazioni rappresentano la stessa chiave:

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

Specificare entità base

Per entità base, il percorso predecessore è vuoto e la chiave è costituita esclusivamente dal tipo e dall'identificatore dell'entità.

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

Specificare un'entità con predecessori

Per inserire un nuovo messaggio con chiavi principali

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

Per le chiavi create con un'entità principale, il metodo parent() restituisce una chiave che rappresenta l'entità padre:

message_key = initial_revision.key.parent()

Utilizzare gli ID chiave numerici

Puoi creare un'entità senza specificare un ID, nel qual caso il datastore genera automaticamente un ID numerico. Se scegli di specificare alcuni ID e poi consenti a Datastore di generare automaticamente alcuni ID, potresti violare il requisito delle chiavi univoche. Per evitare questo problema, riserva un intervallo di numeri da utilizzare per scegliere gli ID o utilizza gli ID stringa.

Per riservare un intervallo di ID, utilizza il metodo di classe della classe del modello: allocate_ids()

  • per allocare un numero specificato di ID
  • per allocare tutti gli ID fino a un determinato valore massimo.

Allocare ID

Per allocare 100 ID per una determinata classe di modello MyModel:

first, last = MyModel.allocate_ids(100)

Per allocare 100 ID per le entità con chiave principale p:

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

I valori restituiti, first e last, sono il primo e l'ultimo ID (inclusi) allocati. Puoi utilizzarli per creare le chiavi come segue:

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

È garantito che queste chiavi non siano state restituite in precedenza dal generatore di ID interno del datastore e non verranno restituite dalle chiamate future al generatore di ID interno. Tuttavia, il metodo allocate_ids() non verifica se gli ID restituiti sono presenti nel datastore; interagisce solo con il generatore di ID.

Per allocare tutti gli ID fino a un determinato valore massimo:

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

Questo modulo garantisce che tutti gli ID minori o uguali a N siano considerati allocati. I valori restituiti, first e last, indicano l'intervallo di ID riservati da questa operazione. Non è un errore tentare di riservare ID già allocati; in questo caso, first indica il primo ID non ancora allocato e last è l'ultimo ID allocato.