Uma classe que herda da classe Model
representa a estrutura das entidades armazenadas no Datastore.
As aplicações definem classes de modelos para indicar a estrutura das respetivas entidades e, em seguida, instanciam essas classes de modelos para criar entidades.
Todas as classes de modelos têm de herdar (direta ou indiretamente) de Model.
Esta página tem documentação de referência da API. Para uma vista geral, consulte Entidades e chaves da NDB.
Introdução
Uma classe que herda de Model
descreve entidades do Datastore.
Todas as classes de modelos têm de herdar (direta ou indiretamente) de
Model
.
As atribuições simples na definição da classe do modelo podem ser usadas para declarar a estrutura do modelo:
from google.appengine.ext import ndb class Person(ndb.Model): name = ndb.StringProperty() age = ndb.IntegerProperty()
Agora, podemos criar uma entidade Person e escrevê-la no Datastore:
p = Person(name='Arthur Dent', age=42) k = p.put()
O valor devolvido de put()
é uma
Key, que pode ser usada para obter a mesma
entidade mais tarde:
p2 = k.get() p2 == p # Returns True
Para atualizar uma entidade, basta alterar os respetivos atributos e reescrevê-los (tenha em atenção que isto não altera a chave):
p2.name = 'Arthur Philip Dent' p2.put()
Também podemos eliminar uma entidade (através da chave):
k.delete()
As definições de propriedades no corpo da classe indicam ao sistema os nomes e os tipos dos campos a armazenar no Datastore, se têm de ser indexados, o respetivo valor predefinido e muito mais. Existem muitos tipos de propriedades diferentes.
Normalmente, o tipo é igual ao nome da classe (excluindo o nome do módulo ou qualquer outro âmbito principal). Para substituir o tipo (útil
para alterações ao esquema),
defina um método de classe denominado _get_kind()
, da seguinte forma:
class MyModel(ndb.Model): @classmethod def _get_kind(cls): return 'AnotherKind'
Uma aplicação não deve definir duas classes de modelos com o mesmo tipo, mesmo que estejam em módulos diferentes. Os tipos de uma aplicação são considerados um "espaço de nomes" global.
Model
As subclasses podem definir hooks pré-chamada e pós-chamada para a maioria das operações (get, put, delete, allocate_ids).
Construtor
Normalmente, uma aplicação não chama Model()
, mas é provável que chame o construtor de uma classe que herda de Model
.
Isto cria uma nova instância deste modelo, também conhecida como entidade.
A entidade criada recentemente não é escrita automaticamente no Datastore.
Para que isso aconteça, tem de ser escrito no Datastore através de uma chamada explícita para put()
.
Argumentos:
As subclasses Model
suportam estes argumentos de palavras-chave:
- key Instância
- chave para este modelo. Se o parâmetro
key
for usado,id
eparent
têm de serNone
(a predefinição). - id
- ID da chave para este modelo. Se for usado
id
, a chave tem de serNone
(a predefinição). - parent Instância Key para o modelo principal ou
-
Se usar
parent
,key
tem de serNone
. - namespace
- Espaço de nomes a usar para esta entidade ou
None
(predefinição) para usar o espaço de nomes atual. Se usarnamespace
,key
tem de serNone
.
None
para um modelo de nível superior.Uma aplicação também pode usar argumentos de palavras-chave que mapeiam para as propriedades do modelo. Por exemplo, o seguinte funciona:
class Person(ndb.Model): name = StringProperty() age = IntegerProperty() p = Person(name='Arthur Dent', age=42)
Não pode definir facilmente uma propriedade com o nome "key", "id", "parent" ou
"namespace".
Se passar, por exemplo, key="foo"
num construtor ou numa chamada populate()
, define a chave da entidade e não um atributo de propriedade denominado "chave".
Nota:
Se substituir o construtor numa subclasse Model, tenha em atenção que o
construtor também é chamado implicitamente em alguns casos e certifique-se de que
suporta essas chamadas. Quando uma entidade é lida a partir do Datastore,
é criada primeiro uma entidade vazia chamando o construtor sem
argumentos, após o que os valores de chave e propriedade são definidos um a um.
Quando get_or_insert()
ou get_or_insert_async()
cria uma nova instância, transmite
**constructor_args
ao construtor e define a chave posteriormente.
Métodos de classe
- allocate_ids(size=None, max=None, parent=None, **ctx_options)
-
Atribui um intervalo de IDs de chaves a esta classe de modelo.
Argumentos
- size
- Número de IDs a atribuir. Pode especificar
size
oumax
, mas não ambas. - max
- ID máximo a atribuir. Pode especificar
size
oumax
, mas não ambas. - parent
- Chave principal para a qual os IDs vão ser atribuídos.
- **ctx_options
- Opções de contexto
Devolve uma tupla com (início, fim) para o intervalo atribuído, inclusive.
Uma aplicação não pode chamar
allocate_ids()
numa transação. - allocate_ids_async(size=None, max=None, parent=None, **ctx_options)
-
Versão assíncrona de allocate_ids.
Devolve um objeto
Future
cujo resultado é uma tupla com (start, end) para o intervalo atribuído, inclusive. - get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
- Devolve uma entidade por ID. Isto é apenas uma abreviatura de
Key(cls, id).get()
.Argumentos
- id
- Um ID de chave de string ou inteiro.
- parent
- Chave principal do modelo a obter.
- app (argumento de palavra-chave)
- ID da app. Se não for especificado, recebe dados da app atual.
- namespace (argumento de palavra-chave)
- Espaço de nomes. Se não for especificado, recebe dados para o espaço de nomes predefinido.
- **ctx_options
- Opções de contexto
Devolve uma instância do modelo ou
None
se não for encontrada. - get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
- Versão assíncrona de get_by_id.
Devolve um objeto
Future
cujo resultado é uma instância do modelo ouNone
se não for encontrado. - get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
- Recupera transacionalmente uma entidade existente ou cria uma nova.
Argumentos
- key_name
- Um nome de chave (ou seja, um ID de chave de string) para obter ou criar.
- parent
- Chave da entidade principal, se existir.
- app
- ID da app. Se não for especificado, recebe dados da app atual.
- namespace
- Espaço de nomes. Se não for especificado, recebe dados para o espaço de nomes predefinido.
- context_options
- Opções de contexto
Esta função também recebe argumentos de palavras-chave para transmitir ao construtor da classe do modelo se ainda não existir uma instância para o nome da chave especificado. Se já existir uma instância com o
key_name
e o elemento principal fornecidos, estes argumentos são rejeitados.Devolve a instância existente da classe
Model
com o nome da chave especificado e o elemento principal ou um novo que acaba de ser criado.Esta função usa uma transação. Se o código que chama esta função já estiver numa transação, esta função tenta reutilizar a transação existente. Se o grupo de entidades desta função for incompatível com a transação existente, isto pode causar um erro.
- get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
-
Esta é a versão assíncrona de get_or_insert.
Devolve um objeto
Future
cujo resultado é uma instância existente da classeModel
com o nome da chave especificado e o elemento principal ou um novo que acaba de ser criado. - query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)
-
Cria um objeto
Query
para esta classe, conforme descrito em Consultas.O argumento da palavra-chave
distinct
é uma abreviatura de group_by = projection. Todos os outros argumentos de palavras-chave são transmitidos ao construtor de consultas.Se forem fornecidos argumentos posicionais, estes são usados para configurar os filtros iniciais.
Devolve um objeto
Query
.
Métodos de instância
- populate(**constructor_options)
-
Define os valores das propriedades da entidade. Os respetivos argumentos de palavras-chave reconhecem automaticamente os nomes das propriedades da mesma forma que o construtor.
- put(**ctx_options)
-
Escreve os dados da entidade no Datastore. Devolve a chave da entidade.
Argumentos
- **ctx_options
- Opções de contexto
- put_async(**ctx_options)
-
Escreve de forma assíncrona os dados da entidade no Datastore. Devolve um objeto
Future
. O resultado do objetoFuture
vai ser a chave da entidade.Argumentos
- **ctx_options
- Opções de contexto
- to_dict(include=all, exclude=None)
-
Devolve um
dict
que contém os valores das propriedades do modelo. Os valores das propriedades paraStructuredProperty
eLocalStructuredProperty
são convertidos recursivamente em dicionários.Argumentos:
- incluir
- Lista opcional de propriedades a incluir. Predefinição: todos.
- excluir
- Lista opcional de propriedades a excluir. Se existir uma sobreposição entre incluir e excluir, então excluir "ganha".
Nota: se o valor de uma propriedade for um objeto mutável (por exemplo, uma lista que representa uma propriedade repetida ou um dicionário ou uma lista armazenada num
JsonProperty
), a menos que o valor seja convertido explicitamente (por exemplo, no caso de umStructuredProperty
), é devolvido o mesmo objeto no dicionário armazenado na entidade. Nestes casos, a alteração do dicionário altera a entidade e vice-versa.
Dados da instância
- key
- Propriedade especial para armazenar a chave do modelo.
Métodos de chamarizes
Uma subclasse de Model
de uma aplicação pode definir um ou mais destes métodos como métodos de "gancho" pré ou pós-operação.
Por exemplo, para executar algum código antes de cada "get", defina o método _pre_get_hook()
da subclasse do modelo. Para obter conselhos sobre como escrever funções de gancho, consulte Ganchos de modelos.
- @classmethod
_pre_allocate_ids_hook(cls, size, max, parent) - Hook que é executado antes de
allocate_ids()
- @classmethod
_post_allocate_ids_hook(cls, size, max, parent, future) - Hook que é executado após
allocate_ids()
- @classmethod
_pre_delete_hook(cls, key) - Hook que é executado antes de
delete()
- @classmethod
_post_delete_hook(cls, key, future) - Hook que é executado após
delete()
- @classmethod
_pre_get_hook(cls, key) - Hook que é executado antes de
Key.get()
quando recebe uma entidade deste modelo. - @classmethod
_post_get_hook(cls, key, future) - Hook que é executado após
Key.get()
quando recebe uma entidade deste modelo. - _pre_put_hook(self)
- Hook que é executado antes de
put()
- _post_put_hook(self, future)
- Hook que é executado após
put()
Introspeção
Pode usar estes métodos para inspecionar as propriedades e a configuração de um determinado modelo. Isto é útil se estiver a escrever uma biblioteca ou uma função que aceite vários tipos de modelos.
Procura por tipo
Cada modelo tem um tipo que é normalmente igual ao nome da classe, a menos que seja substituído. Pode usar o tipo para encontrar a classe do modelo associada através de
_lookup_model
.
class Animal(ndb.Model): type = ndb.StringProperty() print Animal._get_kind() # 'Animal' print ndb.Model._lookup_model('Animal') # class Animal
Tenha em atenção que _lookup_model
só funciona para classes de modelos que já tenham sido importadas pela aplicação.
Propriedades
Pode obter uma lista de todas as propriedades associadas a um modelo através de _properties
.
class User(ndb.Model): name = ndb.StringProperty() email = ndb.StringProperty() print User._properties # {'email': StringProperty('email'), 'name': StringProperty('name')}
_properties
também funciona para instâncias do 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)}
As instâncias de propriedades podem ser analisadas. As
opções fornecidas ao construtor
estão disponíveis como propriedades com o prefixo _
.
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
Aliases de métodos
Todos os métodos na classe Model
têm um alias com o prefixo _
. Por exemplo,
_put()
é equivalente a put()
. Isto significa que pode ter propriedades
com nomes que entrem em conflito com os nomes dos métodos, desde que use sempre os métodos com o prefixo _
. No entanto, tenha em atenção que não pode especificar nenhuma propriedade com o nome key
, parent
ou id
no construtor.
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.
Se estiver a criar bibliotecas de terceiros que interagem com modelos arbitrários,
é recomendável usar os métodos com o prefixo _
-.