Module 3: Migrer de Google Cloud NDB vers Cloud Datastore

1. Présentation

Cette série d'ateliers de programmation (tutoriels pratiques et d'auto-formation) vise à aider les développeurs Google App Engine (environnement standard) à moderniser leurs applications en les guidant lors d'une série de migrations. L'étape la plus importante est de délaisser les services groupés de l'environnement d'exécution d'origine, car les environnements d'exécution nouvelle génération sont plus souples et offrent aux utilisateurs davantage d'options de service. Le passage à l'environnement d'exécution nouvelle génération vous permet d'intégrer plus facilement les produits Google Cloud, d'utiliser une plus large gamme de services compatibles et de prendre en charge les versions de langage actuelles.

Ce tutoriel facultatif montre aux développeurs comment migrer de Cloud NDB vers Cloud Datastore en tant que bibliothèque cliente pour communiquer avec le service Datastore. Les développeurs qui préfèrent la bibliothèque NDB peuvent continuer à l'utiliser, car elle est compatible avec Python 3. C'est pourquoi cette migration est facultative. Cette migration est réservée aux utilisateurs qui souhaitent créer un codebase cohérent et des bibliothèques partagées avec d'autres applications utilisant déjà Cloud Datastore. Pour en savoir plus, reportez-vous à la section "Contexte". .

Vous apprendrez à effectuer les tâches suivantes :

  • Utiliser Cloud NDB (si vous ne le savez pas)
  • Migrer de Cloud NDB vers Cloud Datastore
  • Migrer votre application vers Python 3

Prérequis

  • Un projet Google Cloud Platform avec un compte de facturation GCP actif
  • Des connaissances de base en Python
  • Bonne connaissance des commandes Linux de base
  • Connaissances de base sur le développement et le déploiement d'applications App Engine
  • Une application App Engine 2.x ou 3.x opérationnelle du module 2.

Enquête

Comment allez-vous utiliser cet atelier de programmation ?

<ph type="x-smartling-placeholder"></ph> Je vous invite à le lire uniquement Je vais le lire et effectuer les exercices
.

2. Contexte

Bien que Cloud NDB soit une excellente solution Datastore pour les développeurs App Engine de longue date et facilite la transition vers Python 3, ce n'est pas le seul moyen pour les développeurs App Engine d'accéder à Datastore. Lorsque Datastore est devenu son propre produit en 2013, Google Cloud Datastore, une nouvelle bibliothèque cliente a été créée afin que tous les utilisateurs puissent utiliser Datastore.

Les développeurs Python 3 qui utilisent App Engine et non App Engine sont invités à utiliser Cloud Datastore (et non Cloud NDB). Les développeurs App Engine Python 2 sont encouragés à migrer de ndb vers Cloud NDB et à passer à Python 3 à partir de là. Ils peuvent également choisir de migrer vers Cloud Datastore. Cette décision est logique, surtout pour les développeurs qui disposent déjà de code utilisant Cloud Datastore, comme ceux que nous venons de mentionner, et qui souhaitent créer des bibliothèques partagées dans toutes leurs applications. La réutilisation du code est une bonne pratique, tout comme la cohérence du code. Les deux contribuent à réduire les coûts de maintenance globaux, comme résumé ici:

Migration de Cloud NDB vers Cloud Datastore

  • Permet aux développeurs de se concentrer sur un seul codebase pour l'accès à Datastore
  • Évite de conserver une partie du code avec Cloud NDB et d'autres à l'aide de Cloud Datastore
  • Amélioration de la cohérence du codebase et de la réutilisation du code
  • Permet d'utiliser des bibliothèques communes/partagées, ce qui contribue à réduire les coûts de maintenance globaux

Cette migration comprend les principales étapes suivantes:

  1. Configuration/Préparation
  2. Remplacer Cloud NDB par des bibliothèques clientes Cloud Datastore
  3. Mettre à jour l'application

3. Configuration/Préparation

Avant de passer à la partie principale de ce tutoriel, nous allons configurer notre projet, obtenir le code et déployer l'application de base pour nous assurer de bien utiliser du code fonctionnel.

1. Configurer le projet

Si vous avez terminé l'atelier de programmation du module 2, nous vous recommandons de réutiliser le même projet (et le même code). Vous pouvez également créer un projet ou réutiliser un autre projet existant. Assurez-vous que le projet dispose d'un compte de facturation actif et que App Engine (app) est activé.

2. Obtenir un exemple d'application de référence

Pour cela, vous devez disposer d'une application exemple du module 2 fonctionnelle. Utilisez votre solution si vous avez terminé ce tutoriel. Vous pouvez le terminer maintenant (lien ci-dessus) ou, si vous souhaitez l'ignorer, copier le dépôt du module 2 (lien ci-dessous).

Que vous utilisiez le vôtre ou le nôtre, nous allons commencer par le code du module 2. Cet atelier de programmation du module 3 vous guide à travers chaque étape. Une fois l'atelier terminé, il doit ressembler à du code au point TERMINÉ. Il existe des versions Python 2 et 3 de ce tutoriel. Vous devez donc récupérer le dépôt de code approprié ci-dessous.

Python 2

Pour Python 2, le répertoire de départ (votre code ou notre code) doit ressembler à ce qui suit :

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

Si vous avez terminé le tutoriel du module 2, vous disposez également d'un dossier lib avec Flask et ses dépendances. Si vous n'avez pas de dossier lib, créez-le à l'aide de la commande pip install -t lib -r requirements.txt afin que nous puissions déployer cette application de référence à l'étape suivante. Si Python 2 et Python 3 sont tous les deux installés, nous vous recommandons d'utiliser pip2 plutôt que pip afin d'éviter toute confusion avec Python 3.

Python 3

Le répertoire des fichiers de démarrage Python 3 Module 2 (les vôtres ou les nôtres) doit se présenter comme suit:

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

Python 3 n'utilise ni lib, ni appengine_config.py.

3. (Re)Déployer l'application du module 2

Étapes préliminaires restantes :

  1. Familiarisez-vous avec l'outil de ligne de commande gcloud (si nécessaire).
  2. (Re)déployez le code du module 1 sur App Engine (si nécessaire).

Une fois que vous avez exécuté ces étapes et vérifié le bon fonctionnement du code, nous pouvons passer à la suite de ce tutoriel en commençant par les fichiers de configuration.

4. Remplacer Cloud NDB par des bibliothèques clientes Cloud Datastore

La seule modification de configuration est un échange mineur de package dans votre fichier requirements.txt.

1. Mettre à jour requirements.txt

À la fin du module 2, votre fichier requirements.txt se présentait comme suit:

  • AVANT (Python 2 et 3):
Flask==1.1.2
google-cloud-ndb==1.7.1

Mettez à jour requirements.txt en remplaçant la bibliothèque Cloud NDB (google-cloud-ndb) par la dernière version de la bibliothèque Cloud Datastore (google-cloud-datastore), en laissant l'entrée Flask intacte, en gardant à l'esprit que la version finale de Cloud Datastore compatible avec Python 2 est la version 1.15.3:

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

N'oubliez pas que le dépôt est géré plus régulièrement que ce tutoriel. Il est donc possible que le fichier requirements.txt contienne des versions plus récentes. Nous vous recommandons d'utiliser les dernières versions de chaque bibliothèque, mais si elles ne fonctionnent pas, vous pouvez effectuer un rollback vers une version plus ancienne. Les numéros de version ci-dessus correspondent à la dernière mise à jour de cet atelier de programmation.

2. Autres fichiers de configuration

Les autres fichiers de configuration, app.yaml et appengine_config.py, ne doivent pas être modifiés par rapport à l'étape de migration précédente:

  • app.yaml doit (toujours) faire référence aux packages groupés tiers grpcio et setuptools.
  • appengine_config.py doit (toujours) rediriger pkg_resources et google.appengine.ext.vendor vers les ressources tierces dans lib.

Passons maintenant aux fichiers d'application.

5. Mettre à jour les fichiers de l'application

Aucune modification n'a été apportée à template/index.html, mais quelques modifications ont été apportées à main.py.

1. Importations

Le code de départ de la section d'importation doit se présenter comme suit:

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

Remplacez l'importation google.cloud.ndb par une autre pour Cloud Datastore: google.cloud.datastore. Étant donné que la bibliothèque cliente Datastore n'accepte pas la création automatique d'un champ d'horodatage dans une entité, importez également le module datetime de la bibliothèque standard pour en créer un manuellement. Par convention, les importations de bibliothèques standards dépassent les importations de packages tiers. Une fois ces modifications effectuées, le code devrait se présenter comme suit:

  • APRÈS :
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore

2. Initialisation et modèle de données

Après avoir initialisé Flask, l'application exemple du module 2 crée une classe de modèle de données NDB et ses champs, comme suit:

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

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

La bibliothèque Cloud Datastore ne possède pas cette classe. Vous devez donc supprimer la déclaration de classe Visit. Comme vous avez toujours besoin d'un client pour communiquer avec Datastore, remplacez ndb.Client() par datastore.Client(). La bibliothèque Datastore est plus "flexible" vous permettant de créer des entités sans "pré-déclaration" leur structure, comme le langage Kotlin. Après cette mise à jour, cette partie de main.py devrait se présenter comme suit:

  • APRÈS :
app = Flask(__name__)
ds_client = datastore.Client()

3. Accès à Datastore

La migration vers Cloud Datastore nécessite de modifier la façon dont vous créez, stockez et interrogez les entités Datastore (au niveau de l'utilisateur). Pour vos applications, la difficulté de cette migration dépend de la complexité de votre code Datastore. Dans notre application exemple, nous avons essayé de simplifier au maximum la mise à jour. Voici notre code de départ:

  • AVANT :
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])

Avec Cloud Datastore, créez une entité générique en identifiant les objets groupés dans votre entité à l'aide d'une "clé". Créez l'enregistrement de données avec un objet JSON (dict Python) de paires clé-valeur, puis écrivez-le dans Datastore avec le put() attendu. L'interrogation est semblable, mais plus simple, avec Datastore. Ici, vous pouvez voir en quoi le code Datastore équivalent diffère:

  • APRÈ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)

Mettez à jour le corps des fonctions pour store_visit() et fetch_visits() comme indiqué ci-dessus, en conservant leurs signatures identiques à celles de la version précédente. Aucune modification n'a été apportée au gestionnaire principal root(). Une fois ces modifications effectuées, votre application est prête à utiliser Cloud Datastore et prête à être testée.

6. Résumé/Nettoyage

Déployer l'application

Redéployez votre application avec gcloud app deploy et confirmez qu'elle fonctionne correctement. Votre code doit maintenant correspondre à ce qui se trouve dans les dossiers du dépôt du module 3:

Si vous avez consulté cette série sans suivre les ateliers de programmation précédents, l'application elle-même ne change pas. Elle enregistre toutes les visites sur la page Web principale (/) et ressemble à ceci une fois que vous avez consulté le site suffisamment de fois :

Application Visitme

Félicitations, vous avez terminé cet atelier de programmation du module 3. Vous savez maintenant que vous pouvez utiliser les bibliothèques clientes Cloud NDB et Cloud Datastore pour accéder à Datastore. En migrant vers cette dernière version, vous pouvez désormais bénéficier des avantages suivants : bibliothèques partagées, code commun et réutilisation de code pour plus de cohérence et de coûts de maintenance réduits.

Facultatif : Effectuer un nettoyage

Que diriez-vous d'un bon nettoyage pour éviter que des frais vous soient facturés tant que vous n'êtes pas prêt à passer à l'atelier de programmation suivant sur la migration ? En tant que développeur existant, vous connaissez probablement déjà les informations de tarification d'App Engine.

Facultatif : Désactiver l'application

Si vous n'êtes pas encore prêt à passer au tutoriel suivant, désactivez votre application pour éviter les frais. Lorsque vous serez prêt à passer au prochain atelier de programmation, vous pourrez le réactiver. Tant que votre application est désactivée, elle ne génère aucun trafic, donc aucuns frais. Toutefois, si vous dépassez le quota gratuit, votre utilisation de Datastore vous sera facturée alors supprimez suffisamment d'éléments pour rester dans la limite.

En revanche, si vous ne souhaitez pas poursuivre vos migrations et souhaitez supprimer tous les éléments, vous pouvez arrêter le projet.

Étapes suivantes

À partir de là, n'hésitez pas à explorer les prochains modules de migration:

  • Bonus du module 3:passez à la section bonus pour apprendre à transférer des données vers Python 3 et l'environnement d'exécution App Engine nouvelle génération.
  • Module 7 : files d'attente d'envoi de tâches App Engine (obligatoire si vous utilisez des files d'attente de tâches d'envoi de tâches [push])
    • Ajoutez des tâches push taskqueue App Engine à l'application du module 1.
    • Préparez les utilisateurs à migrer vers Cloud Tasks dans le module 8.
  • Module 4 : Migrer vers Cloud Run avec Docker
    • Conteneurisez votre application pour l'exécuter sur Cloud Run avec Docker.
    • Cela vous permet de continuer d'utiliser Python 2.
  • Module 5 : Migrer vers Cloud Run avec les packs de création Cloud
    • Conteneurisez votre application pour qu'elle s'exécute sur Cloud Run avec les packs de création Cloud.
    • Vous n'avez pas besoin de connaître Docker, les conteneurs ou les Dockerfile.
    • Vous devez avoir déjà effectué la migration de votre application vers Python 3.
  • Module 6 : Migrer vers Cloud Firestore
    • Migrer vers Cloud Firestore pour utiliser les fonctionnalités de Firebase.
    • Bien que Cloud Firestore soit compatible avec Python 2, cet atelier de programmation n'est disponible que pour Python 3.

7. BONUS : Migrer vers Python 3

Pour bénéficier des nouvelles fonctionnalités et des derniers environnements d'exécution App Engine, nous vous recommandons de migrer vers Python 3. Dans notre exemple d'application, Datastore était le seul service intégré utilisé. La migration de ndb vers Cloud NDB ayant été effectuée, nous pouvons maintenant transitionner vers l'environnement d'exécution Python 3 d'App Engine.

Présentation

Bien que le portage vers Python 3 dépasse le cadre d'un simple tutoriel Google Cloud, la présente partie de notre atelier de programmation donne aux développeurs une idée des spécificités de l'environnement d'exécution App Engine pour Python 3. L'environnement d'exécution nouvelle génération offre un accès simplifié aux packages tiers. Il n'est pas nécessaire de spécifier des packages intégrés dans app.yaml ni de copier ou d'importer des bibliothèques non intégrées. ils sont implicitement installés et ne sont pas répertoriés dans requirements.txt.

Notre exemple est très basique et Cloud Datastore est compatible avec Python 2-3. Par conséquent, aucun code d'application n'a besoin d'être explicitement porté sur la version 3.x. L'application s'exécute sur les versions 2.x et 3.x non modifiées, ce qui signifie que les seules modifications requises sont dans la configuration dans ce cas :

  1. Simplification de app.yaml pour référencer Python 3 et supprimer toute référence à des bibliothèques tierces intégrées.
  2. Supprimer appengine_config.py et le dossier lib car ils ne sont plus nécessaires.

Les fichiers d'application main.py et templates/index.html restent inchangés.

Mettre à jour requirements.txt

La version finale de Cloud Datastore compatible avec Python 2 est la version 1.15.3. Mettez à jour requirements.txt avec la dernière version pour Python 3 (peut être plus récente à ce stade). Au moment de la rédaction de ce tutoriel, la dernière version était la 2.1.0. Modifiez donc cette ligne pour qu'elle se présente comme suit (ou toute version la plus récente):

google-cloud-datastore==2.1.0

Simplier app.yaml

AVANT :

La seule réelle modification pour cet exemple d'application est le fait de raccourcir app.yaml. Pour rappel, voici ce que nous avons fait en app.yaml à la fin du module 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

APRÈS :

Dans Python 3, les instructions threadsafe, api_version et libraries sont toutes obsolètes. Toutes les applications sont supposées être threadsafe et api_version n'est plus utilisé dans Python 3. Comme aucun package tiers intégré n'est préinstallé sur les services App Engine, le service libraries est également obsolète. Pour plus d'informations sur ces modifications, consultez la documentation sur les modifications apportées à app.yaml. Par conséquent, vous devez supprimer ces trois éléments de app.yaml et passer à une version compatible de Python 3 (voir ci-dessous).

Facultatif: utilisation de la directive handlers

En outre, la directive handlers, qui dirige le trafic vers des applications App Engine spécifiques, a également été abandonnée. Étant donné que l'environnement d'exécution nouvelle génération suppose que les frameworks Web gèrent le routage des applications, tous les "scripts de gestionnaire" doivent être définis sur "auto". En combinant les modifications ci-dessus, vous obtenez ce fichier app.yaml :

runtime: python38

handlers:
- url: /.*
  script: auto

Pour en savoir plus sur script: auto, consultez la page de référence app.yaml.

Supprimer l'instruction handlers

Étant donné que handlers est obsolète, vous pouvez également supprimer toute la section et ne laisser qu'une seule ligne dans votre fichier app.yaml :

runtime: python38

Par défaut, le serveur Web WSGI Gunicorn est disponible pour toutes les applications. Si vous maîtrisez gunicorn, voici la commande qui s'exécute lors d'un démarrage par défaut avec un fichier app.yaml réduit au strict minimum :

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

Facultatif: utilisation de la directive entrypoint

Toutefois, si votre application nécessite une commande de démarrage spécifique, celle-ci peut être spécifiée avec une instruction entrypoint, ce qui génère un app.yaml qui se présente comme suit:

runtime: python38
entrypoint: python main.py

Cet exemple demande spécifiquement un serveur de développement Flask plutôt que d'utiliser gunicorn. Le code qui démarre le serveur de développement doit également être ajouté à votre application pour démarrer sur l'interface 0.0.0.0 sur le port 8080 en ajoutant cette petite section à la fin de main.py :

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

Pour en savoir plus sur entrypoint, consultez la page de référence app.yaml. D'autres exemples et bonnes pratiques sont disponibles dans la documentation sur le démarrage de l'environnement standard App Engine et dans la documentation sur le démarrage de l'environnement flexible App Engine.

Supprimer appengine_config.py et lib

Supprimez le fichier appengine_config.py et le dossier lib. Lors de la migration vers Python 3, App Engine acquiert et installe les packages répertoriés dans requirements.txt.

Le fichier de configuration appengine_config.py permet de reconnaître les bibliothèques et packages tiers, que vous les ayez copiés vous-même ou que vous utilisiez ceux qui sont déjà disponibles sur des serveurs App Engine (intégrés) Voici un résumé des principaux changements lorsque vous passez à Python 3 :

  1. Pas de regroupement de bibliothèques tierces copiées (répertoriées dans requirements.txt).
  2. Pas de pip install dans un dossier lib et pas de dossier lib.
  3. Pas de liste de bibliothèques tierces dans app.yaml.
  4. Pas besoin de référencer une application auprès des bibliothèques tierces, et donc pas de fichier appengine_config.py.

Il vous suffit de répertorier toutes les bibliothèques tierces requises dans requirements.txt.

Déployer l'application

Redéployez votre application pour vous assurer qu'elle fonctionne. Vous pouvez également confirmer la proximité de votre solution avec l'exemple de code Python 3 du module 3. Pour visualiser les différences avec Python 2, comparez le code à sa version Python 2.

Félicitations, vous avez terminé l'étape bonus du module 3 ! Consultez la documentation sur la préparation des fichiers de configuration pour l'environnement d'exécution Python 3. Enfin, consultez le résumé précédent ci-dessus pour connaître les prochaines étapes et le nettoyage.

Préparer votre application

Au moment de procéder à la migration de votre application, vous devez transférer le fichier main.py et les autres fichiers de l'application vers la version 3.x. Il est donc recommandé d'optimiser autant que possible la compatibilité ascendante de votre application 2.x.

Pour ce faire il existe de nombreuses ressources en ligne mais voici quelques conseils essentiels :

  1. Assurez-vous que toutes les dépendances de votre application sont entièrement compatibles avec la version 3.x.
  2. Assurez-vous que votre application s'exécute au moins avec la version 2.6 (de préférence 2.7).
  3. Assurez-vous que l'application réussit en intégralité la suite de tests (avec une couverture minimale de 80 %).
  4. Utilisez des bibliothèques de compatibilité telles que six, Future et/ou Modernize.
  5. Informez-vous sur les principaux problèmes de compatibilité entre les versions 2.x et 3.x.
  6. Toute E/S peut entraîner des incompatibilités entre les chaînes Unicode et les chaînes d'octets.

L'exemple d'application a été conçu pour tenir compte de tous ces aspects, ce qui explique pourquoi l'application s'exécute aussi bien sous 2.x que sous 3.x. Nous pouvons donc nous concentrer sur les modifications à apporter pour utiliser la plate-forme nouvelle génération.

8. Ressources supplémentaires

Problèmes/commentaires concernant le module de migration App Engine en atelier de programmation

Si vous rencontrez des problèmes avec cet atelier de programmation, commencez par faire une recherche avant de les signaler. Liens vers la recherche et la création d'un signalement :

Ressources de migration

Le tableau ci-dessous contient des liens vers les dossiers de dépôt des modules 2 (START) et 3 (FINISH). Vous pouvez également y accéder depuis le dépôt pour toutes les migrations App Engine que vous pouvez cloner ou télécharger sous forme de fichier ZIP.

Atelier de programmation

Python 2

Python 3

Module 2

code

code

Module 3

code

code

Ressources App Engine

Vous trouverez ci-dessous d'autres ressources concernant cette migration spécifique :