Módulo 3: Migra de Google Cloud NDB a Cloud Datastore

1. Descripción general

Esta serie de codelabs (instructivos de autoaprendizaje prácticos) tiene como objetivo ayudar a los desarrolladores de Google App Engine (entorno estándar) a modernizar sus apps guiándolos a través de una serie de migraciones. El paso más importante es dejar de lado los servicios agrupados del entorno de ejecución porque los entornos de ejecución de última generación son más flexibles y ofrecen a los usuarios una mayor variedad de opciones de servicios. El cambio al entorno de ejecución de generación más reciente te permite la integración en productos de Google Cloud con más facilidad, usar una mayor variedad de servicios compatibles y admitir versiones actuales de lenguaje.

En este instructivo opcional, se muestra a los desarrolladores cómo migrar de Cloud NDB a Cloud Datastore como la biblioteca cliente para comunicarse con el servicio de Datastore. Los desarrolladores que prefieren NDB pueden seguir usándolo, ya que es compatible con Python 3, por lo que esta migración es opcional. Esta migración es solo para quienes deseen compilar una base de código coherente y bibliotecas compartidas con otras apps que ya usan Cloud Datastore. Esto se explica en "Segundo plano" sección.

Obtendrás información para hacer las siguientes acciones

  • Usa Cloud NDB (si no lo conoces)
  • Migra de Cloud NDB a Cloud Datastore
  • Migra más tu app a Python 3

Requisitos

  • Un proyecto de Google Cloud Platform con una cuenta de facturación de GCP activa
  • Habilidades básicas de Python
  • Conocimiento práctico de comandos básicos de Linux
  • Conocimientos básicos sobre el desarrollo y la implementación de aplicaciones de App Engine
  • Una app 2.x o 3.x del módulo 2 de App Engine que funcione

Encuesta

¿Cómo usarás este codelab?

Solo leerlo Léelo y completa los ejercicios. .
.

2. Información general

Si bien Cloud NDB es una gran solución de Datastore para los desarrolladores de App Engine que llevan mucho tiempo en App Engine y ayuda con la transición a Python 3, no es la única forma en que los desarrolladores de App Engine pueden acceder a Datastore. Cuando Datastore de App Engine se convirtió en su propio producto en 2013, Google Cloud Datastore, se creó una biblioteca cliente nueva para que todos los usuarios puedan usar Datastore.

Los desarrolladores de App Engine de Python 3 y que no son de App Engine reciben instrucciones para usar Cloud Datastore (no Cloud NDB). Se recomienda a los desarrolladores de App Engine para Python 2 que migren de ndb a Cloud NDB y que transfieran a Python 3 desde allí, pero también pueden optar por migrar a Cloud Datastore. Esta es una decisión lógica, especialmente para los desarrolladores que ya tienen código que usa Cloud Datastore, como los que acaban de mencionar, y que desean crear bibliotecas compartidas en todas sus aplicaciones. La reutilización del código es una práctica recomendada, al igual que la coherencia del código, y ambas contribuyen a una reducción general del costo de mantenimiento, como se resume a continuación:

Migración de Cloud NDB a Cloud Datastore

  • Permite que los desarrolladores se enfoquen en una sola base de código para acceder a Datastore.
  • Evita mantener un código con Cloud NDB y otros con Cloud Datastore.
  • Proporciona más coherencia en la base de código y mejor reutilización del código.
  • Habilita el uso de bibliotecas comunes o compartidas, que contribuyen a reducir los costos generales de mantenimiento.

En esta migración, se presentan los siguientes pasos principales:

  1. Configurar/trabajo previo
  2. Reemplaza Cloud NDB por las bibliotecas cliente de Cloud Datastore
  3. Actualizar aplicación

3. Configurar/trabajo previo

Antes de comenzar con la parte principal del instructivo, configuremos nuestro proyecto, obtengamos el código e implementemos la app de modelo de referencia para que comencemos a trabajar con el código.

1. Configura el proyecto

Si completaste el codelab del módulo 2, te recomendamos que vuelvas a usar ese mismo proyecto (y código). De manera alternativa, puedes crear un proyecto nuevo o reutilizar otro proyecto existente. Asegúrate de que el proyecto tenga una cuenta de facturación activa y que App Engine (app) esté habilitado.

2. Obtén app de ejemplo del modelo de referencia

Uno de los requisitos previos es tener una app de ejemplo del Módulo 2 que funcione. Usa tu solución si completaste ese instructivo. Puedes completarlo ahora (el vínculo está más arriba) o, si quieres omitirlo, copia el repo del Módulo 2 (consulta el vínculo a continuación).

Sin importar si usas el tuyo o el nuestro, comenzaremos en el código del módulo 2. Este codelab del módulo 3 te guía a través de cada paso y, cuando se complete, debería parecerse al código en el punto de FINALIZAR. Hay versiones de Python 2 y 3 de este instructivo, así que toma el repositorio de código correcto a continuación.

Python 2

El directorio de archivos de INICIO del módulo 2 de Python 2 (los tuyos o los nuestros) debe ser similar al siguiente:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Si completaste el instructivo del módulo 2, también tendrás una carpeta lib con Flask y sus dependencias. Si no tienes una carpeta lib, ingrésela con el comando pip install -t lib -r requirements.txt para que podamos implementar esta aplicación de referencia en el siguiente paso. Si tienes instalado Python 2 y 3, se recomienda usar pip2 en lugar de pip para evitar confusiones con Python 3.

Python 3

El directorio de los archivos STARTing del módulo 2 de Python 3 (tuyos o los nuestros) debería verse de la siguiente manera:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

Ni lib ni appengine_config.py se usan para Python 3.

3. (Re)Implementa la app del Módulo 2

Los pasos del trabajo previo restantes para ejecutar ahora sin estos:

  1. Vuelve a familiarizarte con la herramienta de línea de comandos de gcloud (si es necesario).
  2. (Vuelve a )implementa el código del módulo 1 en App Engine (si es necesario).

Después de ejecutar esos pasos de forma correcta y confirmemos que está funcionando, avanzaremos en este instructivo y comenzaremos con los archivos de configuración.

4. Reemplaza Cloud NDB por las bibliotecas cliente de Cloud Datastore

El único cambio de configuración es un intercambio de paquete menor en tu archivo requirements.txt.

1. Actualizar requirements.txt

Después de completar el módulo 2, tu archivo requirements.txt se veía así:

  • ANTES (Python 2 y 3):
Flask==1.1.2
google-cloud-ndb==1.7.1

Para actualizar requirements.txt, reemplaza la biblioteca de Cloud NDB (google-cloud-ndb) por la versión más reciente de la biblioteca de Cloud Datastore (google-cloud-datastore) y deja la entrada de Flask intacta. Ten en cuenta que la versión final de Cloud Datastore compatible con Python 2 es la 1.15.3:

  • DESPUÉS (Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
  • DESPUÉS (Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0

Ten en cuenta que el repositorio se mantiene con mayor frecuencia que este instructivo, por lo que es posible que el archivo requirements.txt refleje versiones más recientes. Recomendamos usar las versiones más recientes de cada biblioteca. Sin embargo, si no funcionan, puedes revertir a una versión anterior. Los números de las versiones anteriores son los más recientes de la última actualización de este codelab.

2. Otros archivos de configuración

Los otros archivos de configuración, app.yaml y appengine_config.py, no deberían cambiar respecto del paso de migración anterior:

  • app.yaml debe (aún) hacer referencia a los paquetes de terceros grpcio y setuptools.
  • appengine_config.py debe (aún) apuntar pkg_resources y google.appengine.ext.vendor a los recursos de terceros en lib.

Ahora, pasemos a los archivos de la aplicación.

5. Actualizar archivos de la aplicación

No hay cambios en template/index.html, pero hay algunas actualizaciones para main.py.

1. Importaciones

El código de inicio para la sección de importación debería verse de la siguiente manera:

  • ANTES:
from flask import Flask, render_template, request
from google.cloud import ndb

Reemplaza la importación de google.cloud.ndb por una para Cloud Datastore: google.cloud.datastore. Debido a que la biblioteca cliente de Datastore no admite la creación automática de un campo de marca de tiempo en una entidad, también importa el módulo datetime de la biblioteca estándar para crear uno de forma manual. Por convención, las importaciones de bibliotecas estándar superan las importaciones de paquetes de terceros. Cuando termines con estos cambios, debería verse de la siguiente manera:

  • DESPUÉS:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore

2. Inicialización y modelo de datos

Después de inicializar Flask, la app de ejemplo del módulo 2 crea una clase de modelo de datos de NBS y sus campos lo siguiente:

  • ANTES:
app = Flask(__name__)
ds_client = ndb.Client()

class Visit(ndb.Model):
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

La biblioteca de Cloud Datastore no tiene esa clase, por lo que debes borrar la declaración de clase Visit. Aún necesitas un cliente para comunicarse con Datastore, así que cambia ndb.Client() a datastore.Client(). La biblioteca de Datastore es más "flexible", lo que te permite crear entidades sin “declarar previamente” su estructura, como NDB. Después de esta actualización, esta parte de main.py debería verse de la siguiente manera:

  • DESPUÉS:
app = Flask(__name__)
ds_client = datastore.Client()

3. Acceso a Datastore

La migración a Cloud Datastore requiere cambiar la forma en que creas, almacenas y consultas las entidades de Datastore (a nivel del usuario). Para tus aplicaciones, la dificultad de la migración depende de lo complejo que sea tu código de Datastore. En nuestra app de ejemplo, intentamos que la actualización fuera lo más sencilla posible. Este es nuestro código de partida:

  • ANTES:
def store_visit(remote_addr, user_agent):
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    with ds_client.context():
        return (v.to_dict() for v in Visit.query().order(
                -Visit.timestamp).fetch_page(limit)[0])

Con Cloud Datastore, crea una entidad genérica e identifica los objetos agrupados en tu entidad con una “clave”. Crea el registro de datos con un objeto JSON (dict de Python) de pares clave-valor y, luego, escríbelo en Datastore con el put() esperado. La consulta es similar, pero más sencilla, con Datastore. Aquí puedes ver cómo se diferencia el código equivalente de Datastore:

  • DESPUÉS:
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)

Actualiza los cuerpos de la función para store_visit() y fetch_visits() como se muestra más arriba, manteniendo sus firmas idénticas a la versión anterior. No se realizaron cambios en el controlador principal root(). Después de completar estos cambios, tu app estará lista para usar Cloud Datastore y estará lista para probarla.

6. Resumen/limpieza

Implemente la aplicación

Vuelve a implementar la app con gcloud app deploy y confirma que funciona. Ahora, tu código debería coincidir con el contenido de las carpetas del repositorio del módulo 3:

Si alcanzaste esta serie sin hacer ninguno de los Codelabs anteriores, la aplicación en sí no cambia. Registra todas las visitas a la página web principal (/) y tendrá esta apariencia una vez que hayas visitado el sitio muchas veces:

app de visitme

Felicitaciones por completar el codelab del módulo 3. Ahora sabes que puedes usar las bibliotecas cliente de Cloud NDB y Cloud Datastore para acceder a Datastore. Si migras a este último recurso, podrás disfrutar de los beneficios de las bibliotecas compartidas, la reutilización de código y código comunes para lograr coherencia y un menor costo de mantenimiento.

Opcional: Limpieza

¿Qué te parece limpiar a fin de evitar que se te facture hasta que estés listo para pasar a la siguiente codelab de migración? Como desarrolladores existentes, es probable que ya estés al día en la información sobre precios de App Engine.

Opcional: Inhabilita la app

Si aún no estás listo para continuar con el siguiente instructivo, inhabilita tu app a fin de evitar que se apliquen cargos. Cuando estés listo para pasar al siguiente codelab, puedes volver a habilitarla. Aunque tu app esté inhabilitada, no recibirá tráfico que genere cargos. Sin embargo, si se excede la cuota gratuita, se te cobrará por el uso de Datastore. así que borra lo suficiente para que quede dentro de ese límite.

Por otro lado, si no vas a continuar con las migraciones y quieres borrar todo por completo, puedes cerrar tu proyecto.

Próximos pasos

Desde aquí, siéntete libre de explorar los próximos módulos de migración:

  • Contenido adicional del módulo 3: Continúa con la sección adicional para aprender a realizar la portabilidad a Python 3 y al entorno de ejecución de App Engine de nueva generación.
  • Módulo 7: Listas de tareas en cola de envío de App Engine (obligatorio si usas las listas de tareas en cola [enviar])
    • Agrega tareas de envío taskqueue de App Engine a la app del módulo 1
    • Prepara a los usuarios para la migración a Cloud Tasks en el módulo 8
  • Módulo 4: Migra a Cloud Run con Docker
    • Organiza tu aplicación en contenedores para que se ejecute en Cloud Run con Docker
    • Te permite quedarte en Python 2
  • Módulo 5: Migra a Cloud Run con Cloud Buildpacks
    • Crea contenedores para tu app a fin de que se ejecute en Cloud Run con paquetes de Cloud Build
    • No necesitas saber nada sobre Docker, contenedores ni Dockerfiles.
    • Requiere que ya hayas migrado tu app a Python 3
  • Módulo 6: Migra a Cloud Firestore
    • Migra a Cloud Firestore para acceder a las funciones de Firebase
    • Si bien Cloud Firestore es compatible con Python 2, este codelab solo está disponible en Python 3.

7. BONIFICACIÓN: migra a Python 3

Para acceder a las funciones y el entorno de ejecución más recientes de App Engine, te recomendamos que migres a Python 3. En nuestra app de muestra, Datastore era el único servicio integrado que usábamos y, desde que migramos de ndb a Cloud NDB, podemos transferir el entorno de ejecución de Python 3 de App Engine.

Descripción general

Si bien la portabilidad a Python 3 no está dentro del alcance de un instructivo de Google Cloud, esta parte del codelab brinda a los desarrolladores una idea de cómo difiere el entorno de ejecución de Python 3 en App Engine. Una característica destacada del entorno de ejecución de nueva generación es el acceso simplificado a paquetes de terceros: No es necesario especificar paquetes integrados en app.yaml ni es necesario copiar o subir bibliotecas no integradas. se instalan de forma implícita a partir de la lista de requirements.txt.

Debido a que nuestra muestra es tan básica y Cloud Datastore es compatible con Python 2-3, no es necesario transferir ningún código de la aplicación de forma explícita a 3.x. La app se ejecuta en 2.x y 3.x sin modificaciones, por lo que, en este caso, los únicos cambios requeridos están en la configuración:

  1. Simplifica app.yaml para hacer referencia a Python 3 y quitar la referencia a bibliotecas de terceros empaquetadas.
  2. Borra appengine_config.py y la carpeta lib porque ya no son necesarias.

Los archivos de aplicación main.py y templates/index.html no se modifican.

Actualizar requirements.txt

La versión final de Cloud Datastore compatible con Python 2 es 1.15.3. Actualiza requirements.txt con la versión más reciente de Python 3 (puede ser más reciente por ahora). Cuando se escribió este instructivo, la última versión era 2.1.0, así que edita esa línea para que se vea de la siguiente manera (o la versión más reciente):

google-cloud-datastore==2.1.0

Simplifica app.yaml

ANTES:

El único cambio real para esta app de muestra es acortar app.yaml de manera significativa. Como recordatorio, esto es lo que vimos en app.yaml al final del Módulo 3:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

DESPUÉS:

En Python 3, las directivas threadsafe, api_version y libraries dejaron de estar disponibles. Se supone que todas las apps son seguras para los subprocesos y api_version no se usa en Python 3. Ya no hay paquetes de terceros integrados preinstalados en los servicios de App Engine, por lo que libraries también es obsoleto. Consulta la documentación sobre cambios en app.yaml para obtener más información sobre estos cambios. Como resultado, debes borrar los tres de app.yaml y actualizar a una versión de Python 3 compatible (consulta a continuación).

Opcional: Uso de la directiva handlers

Además, la directiva handlers, que dirige el tráfico en las aplicaciones de App Engine, también dejó de estar disponible. Dado que el entorno de ejecución de última generación espera que los frameworks web administren el enrutamiento de las apps, todas las “secuencias de comandos del controlador” deben cambiarse a “auto”. Si combinas los cambios anteriores, llegarás a este app.yaml:

runtime: python38

handlers:
- url: /.*
  script: auto

Obtén más información sobre script: auto en la página de referencia de app.yaml.

Quita la directiva handlers

Como handlers dejó de estar disponible, también puedes quitar toda la sección y dejar una sola línea app.yaml:

runtime: python38

De forma predeterminada, esto iniciará el servidor web de Gunicorn WSGI, que está disponible para todas las aplicaciones. Si estás familiarizado con gunicorn, este es el comando que se ejecuta cuando se inicia de forma predeterminada con los barebones app.yaml:

gunicorn main:app --workers 2 -c /config/gunicorn.py

Opcional: Uso de la directiva entrypoint

Sin embargo, si la aplicación requiere un comando de inicio específico, se puede especificar con una directiva entrypoint, lo que da como resultado un app.yaml similar al siguiente:

runtime: python38
entrypoint: python main.py

En este ejemplo, se solicita específicamente que se use el servidor de desarrollo de Flask en lugar de gunicorn. El código que inicia el servidor de desarrollo también se debe agregar a tu app para iniciarlo en la interfaz 0.0.0.0 del puerto 8080. Para ello, agrega esta pequeña sección al final de main.py:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Obtén más información sobre entrypoint en la página de referencia de app.yaml. Puedes encontrar más ejemplos y prácticas recomendadas en los documentos de inicio del entorno estándar de App Engine y en los documentos de inicio del entorno flexible de App Engine.

Borra appengine_config.py y lib

Borra el archivo appengine_config.py y la carpeta lib. Durante la migración a Python 3, App Engine adquiere e instala los paquetes que se enumeran en requirements.txt.

El archivo de configuración appengine_config.py se usa para reconocer las bibliotecas o los paquetes de terceros, sin importar si los copiaste o usas los que ya están disponibles en los servidores de App Engine (integrados). Cuando se migra a Python 3, un resumen de los grandes cambios es el siguiente:

  1. No se agruparon las bibliotecas de terceros copiadas (enumeradas en requirements.txt).
  2. No hay pip install en una carpeta lib, lo que significa que no hay un período de carpeta lib
  3. No hay bibliotecas de terceros integradas en app.yaml
  4. No es necesario hacer referencia a la app a bibliotecas de terceros, por lo que no se necesita ningún archivo appengine_config.py

Todo lo que se necesita es enumerar las bibliotecas de terceros en requirements.txt.

Implemente la aplicación

Vuelve a implementar tu app para asegurarte de que funcione. También puedes confirmar qué tan cerca está tu solución del código de muestra de Python 3 del módulo 3. Para visualizar las diferencias con Python 2, compara el código con su versión de Python 2.

¡Felicitaciones por completar el paso adicional en el módulo 3! Consulta la documentación sobre la preparación de archivos de configuración para el entorno de ejecución de Python 3. Por último, revisa el resumen anterior para conocer los próximos pasos y la limpieza.

Preparando tu aplicación

Cuando llegue el momento de migrar tu aplicación, deberás transferir tu main.py y otros archivos de la aplicación a 3.x, por lo que la práctica recomendada es tratar de hacer lo mejor para hacer que tu aplicación 2.x. sea compatible con versiones futuras con la mayor brevedad.

Hay muchos recursos en línea que te ayudarán a lograrlo, pero estos son algunos los consejos clave:

  1. Asegúrate de que todas las dependencias de las aplicaciones sean totalmente compatibles con 3.x
  2. Asegúrate de que la aplicación se ejecute al menos en 2.6 (preferentemente 2.7).
  3. Asegúrate de que la aplicación apruebe el conjunto de pruebas completo (y una cobertura mínima del 80%)
  4. Usa bibliotecas de compatibilidad como six, Future o Modernize.
  5. Infórmate sobre las diferencias clave de incompatibilidad con versiones anteriores (2.x) en comparación con las versiones 3.x
  6. Cualquier E/S tendrá como resultado una incompatibilidad con strings de Unicode en comparación con a la string de bytes

Como la app de muestra se diseñó teniendo en cuenta todo esto, entonces, por qué la app se ejecuta en 2.x y 3.x de inmediato para que podamos enfocarnos en mostrarte lo que se debe cambiar a fin de usar la plataforma de última generación.

8. Recursos adicionales

Problemas o comentarios de los Codelabs del módulo de migración de App Engine

Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:

Recursos de migración

En la siguiente tabla, encontrarás los vínculos a las carpetas de repo del Módulo 2 (COMENZAR) y Módulo 3 (FINALIZAR). También se puede acceder a ellos desde el repositorio de todas las migraciones de App Engine, que puedes clonar o descargar un archivo ZIP.

Codelab

Python 2

Python 3

Módulo 2

código

código

Module 3

código

código

Recursos de App Engine

A continuación, se muestran recursos adicionales con respecto a esta migración específica: