Crear y usar claves de entidad

Cada entidad se identifica mediante una clave única en la instancia de Datastore de la aplicación y consta de lo siguiente:

  • kind. Normalmente, el tipo es el nombre de la clase de modelo a la que pertenece la entidad, pero puedes cambiarlo por otra cadena anulando el método de clase _get_kind().
  • identifier. Puede especificar su propio nombre de clave como identificador o dejar que Datastore genere automáticamente un ID numérico entero.

Especificar tu propio nombre de clave

En el siguiente ejemplo se crea implícitamente una clave con un identificador de cadena mediante el parámetro con nombre id:

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

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

También puedes definir el nombre de la clave directamente:

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

Permitir que Datastore genere un ID para usarlo como clave

Este código muestra cómo usar un ID generado automáticamente como clave:

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

Usar la ruta de ancestro en la clave

La secuencia de entidades que empieza con una entidad raíz y continúa de la entidad superior a la secundaria hasta llegar a una entidad determinada constituye la ruta de ancestros de esa entidad. Una entidad, su superior, el superior de su superior, etc., son los ancestros de la entidad. Las entidades de Datastore forman un espacio de claves jerárquico similar a la estructura de directorios jerárquica de un sistema de archivos.

La clave completa que identifica una entidad consta de una secuencia de pares de tipo e identificador que especifican su ruta de ancestros y terminan con los de la propia entidad. El método constructor de la clase Key acepta una secuencia de tipos e identificadores y devuelve un objeto que representa la clave de la entidad correspondiente.

En el siguiente ejemplo se muestra un servicio de blogs que almacena mensajes por revisión. Los mensajes se organizan por cuentas y las revisiones se organizan por mensajes.

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

En el ejemplo, ('Account', 'sandy@example.com'), ('Message', 123) y ('Revision', '1') son ejemplos de pares de tipo e identificador.

Ten en cuenta que Message no es una clase de modelo, sino que se usa únicamente para agrupar revisiones, no para almacenar datos.

Como se muestra en el código de ejemplo, el tipo de entidad se designa mediante el último par de tipo y nombre de la lista: ndb.Key('Revision', '1').

Usar parámetros con nombre

Puede usar el parámetro con nombre parent para designar directamente cualquier entidad de la ruta de ancestros. Todas las siguientes notaciones representan la misma clave:

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

Especificar una entidad raíz

En el caso de una entidad raíz, la ruta de ancestro está vacía y la clave se compone únicamente del tipo y el identificador de la entidad.

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

Especificar una entidad con antecesores

Para insertar un nuevo mensaje con claves de padres

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

En el caso de las claves que se han creado con un elemento superior, el método parent() devuelve una clave que representa la entidad superior:

message_key = initial_revision.key.parent()

Usar IDs de claves numéricas

Puedes crear una entidad sin especificar un ID. En ese caso, el almacén de datos genera automáticamente un ID numérico. Si decide especificar algunos IDs y dejar que Datastore genere otros automáticamente, podría incumplir el requisito de que las claves sean únicas. Para evitarlo, reserva un intervalo de números que se usará para elegir IDs o usa IDs de cadena para evitar este problema por completo.

Para reservar un intervalo de IDs, usa el método de clase allocate_ids() de la clase de modelo:

  • para asignar un número específico de IDs
  • para asignar todos los IDs hasta un valor máximo determinado.

Asignación de IDs

Para asignar 100 IDs a una clase de modelo determinada MyModel:

first, last = MyModel.allocate_ids(100)

Para asignar 100 IDs a entidades con la clave principal p, haz lo siguiente:

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

Los valores devueltos, first y last, son los IDs primero y último (inclusive) que se han asignado. Puedes usarlas para crear claves de la siguiente manera:

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

Se garantiza que estas claves no las ha devuelto anteriormente el generador de IDs interno del almacén de datos ni se devolverán en futuras llamadas al generador de IDs interno. Sin embargo, el método allocate_ids() no comprueba si los IDs devueltos están presentes en el almacén de datos, sino que solo interactúa con el generador de IDs.

Para asignar todos los IDs hasta un valor máximo determinado, sigue estos pasos:

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

Este formulario asegura que todos los IDs menores o iguales que N se consideren asignados. Los valores devueltos, first y last, indican el intervalo de IDs reservados por esta operación. No se produce ningún error si se intenta reservar IDs que ya se han asignado. En ese caso, first indica el primer ID que aún no se ha asignado y last es el último ID asignado.