Como armazenar dados no Cloud Datastore

Nesta parte da explicação sobre o código em Python do Guestbook, você aprende a armazenar dados estruturados no Cloud Datastore. Com o App Engine e o Cloud Datastore, você não precisa se preocupar com distribuição, replicação e balanceamento de carga de dados. Isso é feito para você por meio de uma API simples. Além disso, você recebe um poderoso mecanismo de consulta e transações.

Esta página é parte de um tutorial com várias páginas. Para começar e ver as instruções de configuração, acesse Como criar um aplicativo Guestbook.

Como armazenar as saudações enviadas

Os dados são gravados no Cloud Datastore em objetos conhecidos como entidades. Cada entidade tem uma chave que a identifica de forma exclusiva. Como alternativa, uma entidade pode designar outra entidade como pai. A primeira entidade é o filho da entidade pai. Assim, no armazenamento de dados, as entidades formam um espaço hierarquicamente estruturado, semelhante à estrutura de diretórios de um sistema de arquivos. Para mais informações, veja Como estruturar dados para consistência forte.

O App Engine inclui uma API de modelagem de dados para Python. Para usar a API de modelagem de dados, o aplicativo de amostra importa o módulo google.appengine.ext.ndb. Cada saudação inclui o nome do autor, o conteúdo da mensagem, a data e hora em que a mensagem foi postada. O aplicativo exibe mensagens em ordem cronológica. O código abaixo define o modelo de dados:

class Author(ndb.Model):
    """Sub model for representing an author."""
    identity = ndb.StringProperty(indexed=False)
    email = ndb.StringProperty(indexed=False)

class Greeting(ndb.Model):
    """A main model for representing an individual Guestbook entry."""
    author = ndb.StructuredProperty(Author)
    content = ndb.StringProperty(indexed=False)
    date = ndb.DateTimeProperty(auto_now_add=True)

O código define um modelo de Greeting com três propriedades: author, em que o valor é um objeto Author com o endereço de e-mail e a identidade do autor, content, em que o valor é uma string e date, em que o valor é um datetime.datetime.

Alguns construtores de propriedades usam parâmetros para configurar ainda mais esse comportamento. Ao transferir o construtor ndb.StringProperty, o parâmetro indexed=False informa que os valores para essa propriedade não serão indexados. Isso economiza gravações desnecessárias porque o aplicativo nunca usa essa propriedade em uma consulta. Ao transferir o construtor ndb.DateTimeProperty, um parâmetro auto_now_add=True configura o modelo para que forneça automaticamente a novos objetos um carimbo de datetime do horário em que o objeto foi criado, caso o aplicativo não forneça um valor. Para uma lista completa dos tipos de propriedades e respectivas opções, veja Propriedades do NDB.

O aplicativo usa o modelo de dados para criar novos objetos Greeting e colocá-los no Cloud Datastore. O gerenciador do Guestbook cria novas saudações e as salva no armazenamento de dados:

class Guestbook(webapp2.RequestHandler):

    def post(self):
        # We set the same parent key on the 'Greeting' to ensure each
        # Greeting is in the same entity group. Queries across the
        # single entity group will be consistent. However, the write
        # rate to a single entity group should be limited to
        # ~1/second.
        guestbook_name = self.request.get('guestbook_name',
                                          DEFAULT_GUESTBOOK_NAME)
        greeting = Greeting(parent=guestbook_key(guestbook_name))

        if users.get_current_user():
            greeting.author = Author(
                    identity=users.get_current_user().user_id(),
                    email=users.get_current_user().email())

        greeting.content = self.request.get('content')
        greeting.put()

        query_params = {'guestbook_name': guestbook_name}
        self.redirect('/?' + urllib.urlencode(query_params))

Este gerenciador do Guestbook cria um novo objeto Greeting. Em seguida, configura as respectivas propriedades, author e content, com os dados postados pelo usuário. O pai da Greeting é uma entidade do Guestbook. Não é necessário criar a entidade do Guestbook antes de configurá-la como pai de outra entidade. Neste exemplo, o pai é usado como um marcador para fins de transação e consistência. Para mais informações, veja a página Transações. Objetos que compartilham um ancestral comum pertencem ao mesmo grupo de entidades. O código não configura a propriedade date. Portanto, a date é configurada automaticamente para o presente, usando auto_now_add=True.

Finalmente, greeting.put() salva o novo objeto no armazenamento de dados. Caso tivéssemos adquirido esse objeto de uma consulta, put() teria atualizado o objeto existente. Como criamos esse objeto com o construtor do modelo, put() adiciona o novo objeto ao armazenamento de dados.

Como a consulta no Cloud Datastore é altamente consistente apenas nos grupos de entidades, o código atribui todas as saudações de um livro ao mesmo grupo de entidades, configurando o mesmo pai para cada saudação. Isso quer dizer que o usuário sempre vê uma saudação imediatamente depois de ela ser gravada. Entretanto, a taxa com que você grava no mesmo grupo de entidades é limitada a uma gravação para o grupo de entidades por segundo. Tenha isso em mente quando projetar seu aplicativo real. Observe que, ao usar serviços como o Memcache, você diminui a chance de um usuário ver resultados obsoletos ao consultar vários grupos de entidades após uma gravação.

Como recuperar saudações enviadas

O Cloud Datastore tem um mecanismo de consulta sofisticado para modelos de dados. Como o Cloud Datastore não é um banco de dados relacional tradicional, as consultas não são especificadas usando o SQL. Em vez disso, os dados são consultados de duas formas: com consultas do Datastore ou com uma linguagem de consulta semelhante ao SQL, chamada GQL. Para acessar todos os recursos de consulta do Cloud Datastore, recomendamos o uso de consultas no GQL.

O gerenciador MainPage recupera e exibe saudações enviadas anteriormente. A consulta é executada com a chamada greetings_query.fetch(10).

Mais informações sobre os índices do Cloud Datastore

Cada consulta no Cloud Datastore é calculada a partir de um ou mais índices, tabelas que mapeiam valores de propriedades ordenados para as chaves de entidade. Dessa forma, o App Engine consegue fornecer resultados rapidamente, seja qual for o tamanho do armazenamento de dados do aplicativo. Muitas consultas são calculadas a partir dos índices integrados, mas para consultas mais complexas, o Cloud Datastore requer um índice personalizado. Sem esse índice, ele não consegue executar essas consultas de forma eficiente.

Por exemplo, o aplicativo Guestbook filtra por livro de visitas e ordena por data, usando uma consulta de ancestral e uma ordem de classificação. Isso requer um índice personalizado a ser especificado no arquivo index.yaml do aplicativo. É possível editar esse arquivo manualmente ou tratar dele de forma automática, executando as consultas no aplicativo localmente. Após o índice ser definido em index.yaml, a implantação do aplicativo também implanta as informações de índice personalizadas.

A definição da consulta em index.yaml é semelhante a esta:

indexes:
- kind: Greeting
  ancestor: yes
  properties:
  - name: date
    direction: desc

Saiba mais sobre os índices do Cloud Datastore na página de Índices do Datastore. Leia sobre a especificação adequada para arquivos index.yaml em Como configurar índices do Datastore em Python.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Python 2