Una clase que hereda de la clase Model
representa la estructura de las entidades almacenadas en Datastore.
Las aplicaciones definen clases de modelo para indicar la estructura de sus entidades y, a continuación, instancian esas clases de modelo para crear entidades.
Todas las clases de modelo deben heredar (directa o indirectamente) de Model.
Esta página contiene documentación de referencia de la API. Para obtener una descripción general, consulta Entidades y claves de NDB.
Introducción
Una clase que hereda de Model
describe las entidades de Datastore.
Todas las clases de modelo deben heredar (directa o indirectamente) de
Model
.
Se pueden usar asignaciones sencillas en la definición de la clase de modelo para declarar la estructura del modelo:
from google.appengine.ext import ndb class Person(ndb.Model): name = ndb.StringProperty() age = ndb.IntegerProperty()
Ahora podemos crear una entidad Person y escribirla en Datastore:
p = Person(name='Arthur Dent', age=42) k = p.put()
El valor devuelto de put()
es una clave, que se puede usar para recuperar la misma entidad más adelante:
p2 = k.get() p2 == p # Returns True
Para actualizar una entidad, solo tienes que cambiar sus atributos y volver a escribirla (ten en cuenta que esto no cambia la clave):
p2.name = 'Arthur Philip Dent' p2.put()
También podemos eliminar una entidad (usando la clave):
k.delete()
Las definiciones de propiedades del cuerpo de la clase indican al sistema los nombres y los tipos de los campos que se van a almacenar en Datastore, si deben indexarse, su valor predeterminado y más. Hay muchos tipos de propiedades.
El valor de kind suele ser igual al nombre de la clase (sin incluir el nombre del módulo ni ningún otro ámbito superior). Para anular el tipo (útil para los cambios de esquema), define un método de clase llamado _get_kind()
de la siguiente manera:
class MyModel(ndb.Model): @classmethod def _get_kind(cls): return 'AnotherKind'
Una aplicación no debe definir dos clases de modelo con el mismo tipo, aunque estén en módulos diferentes. Los tipos de una aplicación se consideran un "espacio de nombres" global.
Las subclases de Model
pueden definir hooks previos y posteriores a las llamadas
para la mayoría de las operaciones
(get, put, delete, allocate_ids).
Constructor
Normalmente, una aplicación no llamará a Model()
, pero es probable que llame al constructor de una clase que herede de Model
.
De esta forma, se crea una instancia de este modelo, también conocida como entidad.
La entidad recién creada no se escribe automáticamente en Datastore.
Para que esto ocurra, debe escribirse en Datastore mediante una llamada explícita a put()
.
Argumentos:
Las subclases de Model
admiten estos argumentos de palabras clave:
- clave Instancia
- clave de este modelo. Si se usa el parámetro
key
,id
yparent
deben serNone
(el valor predeterminado). - id
- ID de clave de este modelo. Si se usa
id
, la clave debe serNone
(el valor predeterminado). - parent Instancia de
- clave del modelo superior o
None
de uno de nivel superior. Si se usaparent
,key
debe serNone
. - namespace
- Espacio de nombres que se va a usar
para esta entidad o
None
(valor predeterminado) para usar el espacio de nombres actual. Si se usanamespace
,key
debe serNone
.
Una aplicación también puede usar argumentos de palabras clave que se asignen a las propiedades del modelo. Por ejemplo, lo siguiente funciona:
class Person(ndb.Model): name = StringProperty() age = IntegerProperty() p = Person(name='Arthur Dent', age=42)
No puedes definir fácilmente una propiedad llamada "key", "id", "parent" o "namespace".
Por ejemplo, si pasa key="foo"
en un constructor o una llamada populate()
, se define la clave de la entidad, no un atributo de propiedad llamado "key".
Nota:
Si anulas el constructor en una subclase de Model, ten en cuenta que el constructor también se llama implícitamente en algunos casos. Asegúrate de que admites esas llamadas. Cuando se lee una entidad de Datastore, primero se crea una entidad vacía llamando al constructor sin argumentos. Después, se definen la clave y los valores de las propiedades uno a uno.
Cuando get_or_insert()
o get_or_insert_async()
crea una instancia, pasa
**constructor_args
al constructor y, después, define la clave.
Métodos de clase
- allocate_ids(size=None, max=None, parent=None, **ctx_options)
-
Asigna un intervalo de IDs de clave a esta clase de modelo.
Argumentos
- size
- Número de IDs que se van a asignar. Se puede especificar
size
omax
, pero no ambos. - max
- ID máximo que se puede asignar. Se puede especificar
size
omax
, pero no ambos. - parent
- Clave principal para la que se asignarán los IDs.
- **ctx_options
- Opciones de contexto
Devuelve una tupla con (inicio, fin) del intervalo asignado, ambos incluidos.
Una aplicación no puede llamar a
allocate_ids()
en una transacción. - allocate_ids_async(size=None, max=None, parent=None, **ctx_options)
-
Versión asíncrona de allocate_ids.
Devuelve un objeto
Future
cuyo resultado es una tupla con (inicio, fin) del intervalo asignado, ambos incluidos. - get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
- Devuelve una entidad por ID. Se trata de una abreviatura de
Key(cls, id).get()
.Argumentos
- id
- ID de clave de cadena o entero.
- parent
- Clave superior del modelo que se va a obtener.
- app (argumento de palabra clave)
- ID de la aplicación. Si no se especifica, se obtienen los datos de la aplicación actual.
- namespace (argumento de palabra clave)
- Espacio de nombres. Si no se especifica, obtiene los datos del espacio de nombres predeterminado.
- **ctx_options
- Opciones de contexto
Devuelve una instancia del modelo o
None
si no se encuentra. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Versión asíncrona de get_by_id.
Devuelve un objeto
Future
cuyo resultado es una instancia del modelo oNone
si no se encuentra. - get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
- Recupera de forma transaccional una entidad o crea una.
Argumentos
- key_name
- Nombre de la clave (es decir, un ID de clave de cadena) que se va a recuperar o crear.
- parent
- Clave de la entidad superior, si procede.
- aplicación
- ID de la aplicación. Si no se especifica, se obtienen los datos de la aplicación actual.
- namespace
- Espacio de nombres. Si no se especifica, obtiene los datos del espacio de nombres predeterminado.
- context_options
- Opciones de contexto
Esta función también toma argumentos de palabras clave para pasarlos al constructor de la clase de modelo si aún no existe una instancia para el nombre de clave especificado. Si ya existe una instancia con el
key_name
y el elemento superior proporcionados, se descartarán estos argumentos.Devuelve una instancia de la clase
Model
con el nombre de clave y el elemento superior especificados o una nueva que se acaba de crear.Esta función usa una transacción. Si el código que llama a esta función ya está en una transacción, esta función intenta reutilizar la transacción. Si el grupo de entidades de esta función no es compatible con la transacción, se puede producir un error.
- get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
-
Esta es la versión asíncrona de get_or_insert.
Devuelve un objeto
Future
cuyo resultado es una instancia de la claseModel
con el nombre de clave y el elemento superior especificados, o bien una instancia nueva que se acaba de crear. - query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)
-
Crea un objeto
Query
para esta clase, tal como se describe en Consultas.El argumento de palabra clave
distinct
es una abreviatura de group_by = projection. Todos los demás argumentos de palabras clave se pasan al constructor Query.Si se proporcionan argumentos posicionales, se usan para configurar los filtros iniciales.
Devuelve un objeto
Query
.
Métodos de instancia
- populate(**constructor_options)
-
Define los valores de las propiedades de la entidad. Sus argumentos de palabras clave reconocen automáticamente los nombres de las propiedades de la misma forma que el constructor.
- put(**ctx_options)
-
Escribe los datos de la entidad en Datastore. Devuelve la clave de la entidad.
Argumentos
- **ctx_options
- Opciones de contexto
- put_async(**ctx_options)
-
Escribe de forma asíncrona los datos de la entidad en Datastore. Devuelve un objeto
Future
. El resultado del objetoFuture
será la clave de la entidad.Argumentos
- **ctx_options
- Opciones de contexto
- to_dict(include=all, exclude=None)
-
Devuelve un
dict
que contiene los valores de las propiedades del modelo. Los valores de las propiedadesStructuredProperty
yLocalStructuredProperty
se convierten de forma recursiva en diccionarios.Argumentos:
- incluir
- Lista opcional de propiedades que se van a incluir. Valor predeterminado: all.
- exclude
- Lista opcional de propiedades que se van a excluir. Si hay solapamiento entre incluir y excluir, entonces excluir "gana".
Nota: Si el valor de una propiedad es un objeto mutable (por ejemplo, una lista que representa una propiedad repetida o un diccionario o una lista almacenados en un
JsonProperty
), a menos que el valor se convierta explícitamente (por ejemplo, en el caso de unStructuredProperty
), se devolverá el mismo objeto en el diccionario que se almacena en la entidad. En estos casos, si se modifica el diccionario, se modificará la entidad y viceversa.
Datos de instancia
- clave
- Propiedad especial para almacenar la clave del modelo.
Métodos de gancho
La subclase Model
de una aplicación puede definir uno o varios de estos métodos como métodos "gancho" previos o posteriores a la operación.
Por ejemplo, para ejecutar código antes de cada "get", define el método _pre_get_hook()
de la subclase del modelo. Para obtener consejos sobre cómo escribir funciones de enlace, consulta Enlaces de modelos.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook que se ejecuta antes
allocate_ids()
- @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook que se ejecuta después de
allocate_ids()
- @classmethod
_pre_delete_hook(cls, key) - Hook que se ejecuta antes
delete()
- @classmethod
_post_delete_hook(cls, key, future) - Hook que se ejecuta después de
delete()
- @classmethod
_pre_get_hook(cls, key) - Hook que se ejecuta antes
Key.get()
al obtener una entidad de este modelo. - @classmethod
_post_get_hook(cls, key, future) - Hook que se ejecuta después de
Key.get()
al obtener una entidad de este modelo. - _pre_put_hook(self)
- Hook que se ejecuta antes
put()
- _post_put_hook(self, future)
- Hook que se ejecuta después de
put()
Introspección
Puede usar estos métodos para inspeccionar las propiedades y la configuración de un modelo concreto. Esto resulta útil si estás escribiendo una biblioteca o una función que acepta varios tipos de modelos.
Buscar por tipo
Todos los modelos tienen un tipo que suele ser el mismo que el nombre de la clase, a menos que se anule. Puedes usar el tipo para encontrar la clase de modelo asociada mediante _lookup_model
.
class Animal(ndb.Model): type = ndb.StringProperty() print Animal._get_kind() # 'Animal' print ndb.Model._lookup_model('Animal') # class Animal
Ten en cuenta que _lookup_model
solo funciona con las clases de modelo que ya ha importado la aplicación.
Propiedades
Puedes obtener una lista de todas las propiedades asociadas a un modelo mediante _properties
.
class User(ndb.Model): name = ndb.StringProperty() email = ndb.StringProperty() print User._properties # {'email': StringProperty('email'), 'name': StringProperty('name')}
_properties
también funciona con instancias de Expando.
class Example(ndb.Expando): pass e = Example() e.foo = 1 e.bar = 'blah' e.tags = ['exp', 'and', 'oh'] print e._properties # {'foo': GenericProperty('foo'), 'bar': GenericProperty('bar'), # 'tags': GenericProperty('tags', repeated=True)}
Se pueden introspeccionar las instancias de propiedad. Las opciones proporcionadas al constructor
están disponibles como propiedades con el prefijo _
.
print User._properties['email']._name # 'email' print User._properties['email']._required # False print User._properties['email']._default # None print User._properties['email']._choices # None print User._properties['email']._compressed # False print User._properties['email']._indexed # True print User._properties['email']._compressed # False print User._properties['email']._repeated # False print User._properties['email']._verbose_name # None print isinstance(User._properties['email'], ndb.StringProperty) # True
Alias de método
Todos los métodos de la clase Model
tienen un alias con el prefijo _
. Por ejemplo, _put()
es equivalente a put()
. Esto significa que puedes tener propiedades con nombres que entren en conflicto con nombres de métodos, siempre que utilices los métodos con el prefijo _
. Sin embargo, no puedes especificar ninguna propiedad con los nombres key
, parent
o id
en el constructor.
class MyModel(ndb.Model): put = ndb.StringProperty() query = ndb.StringProperty() key = ndb.StringProperty() entity = MyModel() entity.put = '1' entity.query = '2' entity.key = '3' entity._put() print entity # MyModel(key=Key('MyModel', ...), put=u'1', query=u'2', key=u'3') print MyModel._query().fetch() # same as above.
Si creas bibliotecas de terceros que interactúan con modelos arbitrarios, te recomendamos que utilices los métodos con el prefijo _
.