1. Visão geral
Esta série de codelabs (tutoriais práticos e autoguiados) destina-se a ajudar os desenvolvedores do Google App Engine (Padrão) a modernizar os aplicativos por meio de uma série de migrações. A maioria dessas migrações envolve deixar de usar os serviços originais de pacote em tempo de execução porque os ambientes de execução de última geração são mais flexíveis, oferecendo aos usuários uma variedade maior de opções de serviços. Outra maneira de modernizar um app é fazer upgrade para um produto mais recente, e esse é o assunto deste codelab.
Os usuários do App Engine que acessam o Datastore com as bibliotecas de cliente Cloud NDB ou Cloud Datastore não precisam fazer mais nada. No entanto, o Cloud Firestore representa o mais recente datastore NoSQL escalonável e altamente disponível com recursos do Firebase Realtime Database.
Você está no lugar certo se for um desenvolvedor que se sente obrigado a usar o Firestore para aproveitar os recursos dele ou pelo menos tem interesse suficiente para saber o que a migração envolve. Neste tutorial, você aprende a migrar um app do App Engine usando o Cloud Datastore para o Cloud Firestore.
Você aprenderá como realizar as seguintes tarefas:
- Reconhecer as diferenças entre o Datastore e o Firestore
- Migrar do Cloud Datastore para o Cloud Firestore
O que é necessário
- Um projeto do Google Cloud Platform com:
- Habilidades básicas em Python
- Conhecimento prático de comandos comuns do Linux
- Conhecimento básico sobre como desenvolver e implantar aplicativos do App Engine
- Recomendamos que você conclua o codelab do Módulo 3, incluindo a portabilidade para o Python 3, antes de começar este (Módulo 6).
- Um aplicativo do App Engine em Python 3 do Cloud Datastore do módulo 3 funcional.
Pesquisa
Como você usará este codelab?
2. Contexto
O Datastore do App Engine se tornou um produto independente em 2013, o Google Cloud Datastore, e agora pode ser acessado por desenvolvedores fora do App Engine. No ano seguinte, o Firebase foi comprado pelo Google. Na época, ele era conhecido pelo banco de dados em tempo real.
Nos anos seguintes, as equipes do Firebase e do Cloud Datastore trabalharam na integração de alguns recursos do Firebase ao Datastore. Como resultado, em 2017, a próxima geração do Cloud Datastore foi lançada. Para refletir a herança de alguns recursos do Firebase, ele foi renomeado como Cloud Firestore.
O Cloud Firestore se tornou o mecanismo de armazenamento NoSQL padrão para projetos do Google Cloud. Os novos apps podem usar o Cloud Firestore de forma nativa, enquanto os bancos de dados do Datastore atuais foram convertidos para o Firestore nos bastidores e agora operam como "Firestore no modo Datastore" para preservar a compatibilidade com as operações do Datastore. Como resultado, os aplicativos só podem operar o Cloud Firestore em um desses modos, e não é possível mudar depois de definido.
Atualmente, quando os usuários criam projetos e selecionam uma solução NoSQL, eles precisam escolher entre o Firestore no modo Datastore ou no modo nativo. Depois que os usuários adicionam entidades do Datastore, não é possível mudar para o Firestore. Da mesma forma, depois que o modo nativo do Firestore é selecionado, não é mais possível voltar para o Datastore (ou melhor, para o Firestore no modo Datastore). Leia a página Como escolher entre o Cloud Firestore no modo Datastore ou o modo nativo do Firestore na documentação para mais detalhes. Para migrar um app para o Firestore, é necessário criar um novo projeto, exportar o Datastore e importar para o Firestore. O objetivo deste tutorial é dar aos desenvolvedores uma ideia das diferenças entre o uso do Cloud Datastore e do Cloud Firestore.
Essa migração não é algo que esperamos que os usuários façam. Por isso, ela é opcional. Embora haja vantagens óbvias em usar o Cloud Firestore de forma nativa, como autenticação de cliente, integração de regras do Firebase e, é claro, o banco de dados em tempo real do Firebase, as etapas de migração são "inconvenientes":
- Você precisa usar um projeto diferente do projeto do seu app atual.
- Não é possível mudar para o Firestore no modo nativo um projeto em que um app adicionou entidades do Datastore.
- Da mesma forma, um projeto que selecionou o Firestore no modo nativo não pode voltar para o modo Datastore.
- Não há uma ferramenta de migração que possa transmitir dados de um projeto para outro.
- Alguns recursos críticos do Datastore, incluindo namespaces e uma taxa de transferência de gravação mais alta (>10k/s), não estão disponíveis no Firestore.
- As ferramentas de exportação e importação são cenários "primitivos" e "tudo ou nada".
- Se o app tiver muitas entidades do Datastore, pode levar horas para exportar e importar para o Firestore.
- Durante esse período, seu aplicativo/serviço não poderá gravar/atualizar dados.
- As atividades de migração contam para o uso normal. Se possível, distribua-as nas cotas diárias para minimizar os custos.
- Como o novo serviço é executado em um projeto diferente, você precisa de uma janela para que as atualizações de DNS sejam propagadas.
- O Datastore e o Firestore têm modelos de dados semelhantes, mas diferentes. Por isso, a migração exige a atualização do funcionamento do app/serviço.
- As consultas de ancestral do Datastore agora são consultas de coleção do Firestore (o padrão).
- As consultas de tipo amplo do Datastore são consultas de grupo de coleções do Firestore
- Os índices e o processamento são diferentes etc.
Dito isso, se você tem um app relativamente simples para considerar a migração, está se preparando para simular uma migração ou simplesmente quer saber mais sobre o Datastore e o Firestore, continue!
Usuários do Python 2:este codelab de migração opcional é apresentado apenas em Python 3. No entanto, como o Cloud Firestore também é compatível com a versão 2.x, os usuários podem interpolar as diferenças de uso. Um exemplo é que os registros do Firestore usam strings Unicode (em vez de strings de bytes). Portanto, um indicador inicial u'' é necessário para literais de string do Python 2, o que significa que uma função store_visit() 2.x vai ficar assim:
def store_visit(remote_addr, user_agent):
doc_ref = fs_client.collection(u'Visit')
doc_ref.add({
u'timestamp': datetime.now(),
u'visitor': u'{}: {}'.format(remote_addr, user_agent),
})
Fora isso, a biblioteca de cliente deve operar de maneira semelhante. O único outro problema a ser considerado é que a biblioteca 2.x do Cloud Firestore está "congelada" no que diz respeito ao desenvolvimento. Portanto, cada vez mais recursos/mais novos só estarão disponíveis na biblioteca de cliente 3.x do Firestore.
Ao prosseguir com essa migração, estas são as principais etapas deste tutorial:
- Configuração/Pré-trabalho
- Adicionar biblioteca do Cloud Firestore
- Atualizar arquivos do aplicativo
3. Configuração/Pré-trabalho
Antes de prosseguirmos com a parte principal do tutorial, vamos configurar o nosso projeto, obter o código e, em seguida, implantar o aplicativo de referência para saber que começamos a trabalhar com o código em funcionamento.
1. Configurar projeto
Recomendamos que você reutilize o mesmo projeto usado para concluir o codelab do Módulo 3. Se preferir, crie um novo projeto ou reutilize outro. Verifique se o projeto tem uma conta de faturamento ativa e o App Engine (aplicativo) está ativado.
2. Receber app de amostra do valor de referência
Um dos pré-requisitos para este codelab é ter um aplicativo de exemplo do Módulo 3. Se você não tiver um, conclua o tutorial do Módulo 3 (link acima) antes de continuar. Caso contrário, se você já estiver familiarizado com o conteúdo, comece pegando o código do Módulo 3 abaixo.
Independentemente de você usar o seu ou o nosso, o código do Módulo 3 é o que faremos. Este codelab do Módulo 6 orienta você em cada etapa e, quando concluído, deve ser semelhante ao código no ponto FINISH. Este tutorial está disponível apenas para Python 3.
- INICIAR: repositório do módulo 3
- CONCLUIR: repositório do módulo 6
- Repositório completo (clique ou faça o download do ZIP)
O diretório dos arquivos do Módulo 3 (seu ou de nosso) deve ter a seguinte aparência:
$ ls
README.md main.py templates
app.yaml requirements.txt
3. (Re)implantar o app do módulo 3
As etapas de pré-trabalho restantes para serem executadas agora:
- Familiarize-se com a ferramenta de linha de comando do
gcloud(se necessário). - (Re)implantar o código do Módulo 3 no App Engine (se necessário)
Depois que você concluir essas etapas e confirmar que está em operação, seguiremos neste tutorial, começando com os arquivos de configuração.
Requisitos do Python 2
- Verifique se
app.yaml(ainda) faz referência aos pacotes de terceiros:grpcioesetuptools. - Confira se
appengine_config.pyainda usapkg_resourcesegoogle.appengine.ext.vendorpara direcionar o app a recursos de terceiros. - Na próxima seção, ao atualizar
requirements.txt, usegoogle-cloud-firestore==1.9.0, que é a versão final compatível com 2.x da biblioteca de cliente Python do Firestore.- Se o
requirements.txttiver uma entrada paragoogle-cloud-core, deixe como está. - Exclua
libe reinstale compip install -t lib -r requirements.txt.
- Se o
4. Atualizar arquivos de configuração (adicionar biblioteca do Cloud Firestore)
Além da configuração, as próximas etapas necessárias são atualizar a configuração e os arquivos do aplicativo. Para o primeiro, a única mudança de configuração é uma pequena troca de pacote no arquivo requirements.txt. Vamos fazer isso agora.
Substitua a linha google-cloud-datastore por google-cloud-firestore em requirements.txt para que fique assim:
Flask==1.1.2
google-cloud-firestore==2.0.2
Recomendamos o uso das versões mais recentes de cada biblioteca. Os números de versão acima são as mais recentes no momento da redação deste tutorial. O código na pasta do repositório FINISH é atualizado com mais frequência e pode ter uma versão mais recente.
Não há outras mudanças de configuração, então app.yaml e templates/index.html permanecem como estão.
5. Atualizar arquivos do aplicativo
Há apenas um arquivo de aplicativo, main.py, então todas as alterações nesta seção afetam apenas esse arquivo.
1. Importações
Mudar a importação do pacote é uma pequena alteração de datastore para firestore:
- Antes:
from google.cloud import datastore
- Depois:
from google.cloud import firestore
2. Acesso ao Firestore
Depois de inicializar o Flask, crie o cliente do Firestore. Faça uma mudança semelhante à acima, mas para a inicialização do cliente:
- Antes:
app = Flask(__name__)
ds_client = datastore.Client()
- Depois:
app = Flask(__name__)
fs_client = firestore.Client()
Ao migrar do Cloud NDB para o Cloud Datastore, você já fez o trabalho pesado para chegar ao Cloud Firestore. Com o Datastore, você cria registros de dados na forma de entidades compostas por propriedades comuns e as agrupa por chaves. Os registros de dados no Firestore são documentos, compostos por pares de chave-valor e agrupados em coleções. A migração do Datastore exige que você pense nessas diferenças, porque elas vão aparecer quando você estiver criando registros de dados e fazendo consultas. Os resultados podem variar dependendo da complexidade do código do Datastore.
No Datastore, você faz consultas com base no tipo de entidade, além de critérios de filtragem e classificação. No Firestore, a consulta de dados é semelhante. Vamos ver um exemplo rápido, supondo estes valores de consulta, clientes (ds_client ou fs_client, respectivamente) e importações:
from datetime import datetime
from firestore.Query import DESCENDING
OCT1 = datetime(2020, 10, 1)
LIMIT = 10
Para o Datastore, vamos consultar as dez entidades Visit mais recentes criadas após 1º de outubro de 2020 em ordem decrescente:
query = ds_client.query(kind='Visit')
query.add_filter('timestamp', '>=', datetime(2020, 10, 1))
query.order = ['-timestamp']
return query.fetch(limit=LIMIT)
Faça o mesmo para o Firestore, na coleção Visit:
query = fs_client.collection('Visit')
query.where('timestamp', '>=', datetime(2020, 10, 1))
query.order_by('timestamp', direction=DESCENDING)
return query.limit(LIMIT).stream()
A consulta do app de exemplo é mais simples (sem cláusula "WHERE"). Como uma revisão, aqui está o código do Cloud Datastore:
- Antes:
def store_visit(remote_addr, user_agent):
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
def fetch_visits(limit):
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
return query.fetch(limit=limit)
Ao migrar para o Firestore, você vai perceber que a criação de novos documentos é semelhante às entidades, e as consultas são como as mostradas anteriormente.
- Depois:
def store_visit(remote_addr, user_agent):
doc_ref = fs_client.collection('Visit')
doc_ref.add({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
def fetch_visits(limit):
visits_ref = fs_client.collection('Visit')
visits = (v.to_dict() for v in visits_ref.order_by('timestamp',
direction=firestore.Query.DESCENDING).limit(limit).stream())
return visits
A função principal root() e o arquivo de modelo index.html permanecem os mesmos. Verifique as mudanças, salve, implante e verifique.
6. Resumo/limpeza
Implante o aplicativo
Implante o app novamente com gcloud app deploy e confirme se ele funciona. Agora, seu código precisa corresponder ao que está no repositório do módulo 6 (ou uma versão 2.x, se preferir).
Se você passou para esta série sem fazer qualquer um dos codelabs anteriores, o app em si não muda. Ele registra todas as visitas à página principal da web (/) e tem esta aparência quando o site é acessado muitas vezes:

Parabéns por concluir esta migração opcional do Módulo 6. Essa é provavelmente uma das últimas migrações que você pode fazer em relação ao armazenamento de dados do App Engine. Uma alternativa de migração que você pode considerar é inserir seu app em contêineres para o Cloud Run, se ainda não tiver feito isso. Consulte os módulos 4 e 5 e os codelabs vinculados abaixo.
Opcional: limpar
E a limpeza para evitar cobrança até que você esteja pronto para passar para o próximo codelab de migração? Como você, os desenvolvedores já estão atualizados nas informações de preços do App Engine.
Opcional: desativar app
Se você ainda não estiver pronto para avançar para o próximo tutorial, desative seu app para evitar cobranças. Quando estiver pronto para passar para o próximo codelab, você poderá reativá-lo. Enquanto seu app estiver desativado, ele não vai receber tráfego para gerar custos. No entanto, o uso do Firestore pode ser cobrado se exceder a cota sem custo financeiro. Exclua o suficiente para ficar abaixo desse limite.
Por outro lado, se você não quiser continuar com as migrações e quiser excluir tudo completamente, poderá encerrar seu projeto.
Próximas etapas
Além deste tutorial, há vários outros codelabs de módulos de migração que você pode considerar:
- Módulo 7: filas de tarefas push do App Engine (obrigatório se você usar filas de tarefas [push]
- Adiciona tarefas push
taskqueuedo App Engine ao aplicativo Module 1 - Prepara os usuários a migrar para o Cloud Tasks no Módulo 8
- Adiciona tarefas push
- Módulo 4: migre para o Cloud Run com o Docker
- Contentorize seu app para ser executado no Cloud Run com o Docker
- Essa migração permite que você permaneça no Python 2.
- Módulo 5: Migrar para o Cloud Run com o Cloud Buildpacks
- Contentorize seu app para ser executado no Cloud Run com o Cloud Buildpacks
- Não é preciso saber nada sobre o Docker, os contêineres ou as
Dockerfiles. - Requer que seu app já tenha sido migrado para o Python 3 (o Buildpack não é compatível com o Python 2)
7. Outros recursos
Problemas/comentários do módulo de migração do App Engine
Se você encontrar problemas com este codelab, pesquise seu problema antes de preenchê-lo. Links para pesquisar e criar novos problemas:
Recursos de migração
Os links para as pastas do repositório do módulo 3 (START) e do Módulo 6 (FINISH) podem ser encontrados na tabela abaixo. Elas também podem ser acessadas no repositório de todas as migrações do App Engine, que você pode clonar ou fazer o download de um arquivo ZIP.
Codelab | Python 2 | Python 3 |
(code) | ||
Módulo 6 | (n/a) |
Recursos do App Engine
Veja abaixo mais recursos relacionados a essa migração específica:
- Referências do Python Cloud Datastore e Cloud Firestore
- Como migrar para o ambiente de execução de última geração do Python 3 e do GAE
- Geral