1. Übersicht
Die Codelabs der Reihe „Serverless Migration Station“ (selbstgesteuerte, praktische Anleitungen) und die zugehörigen Videos sollen serverlosen Google Cloud-Entwicklern helfen, ihre Anwendungen zu modernisieren. Dazu werden sie durch eine oder mehrere Migrationen geführt, bei denen es in erster Linie darum geht, von Legacy-Diensten wegzukommen. Dadurch werden Ihre Apps portierbarer und Sie erhalten mehr Optionen und Flexibilität. Sie können eine größere Auswahl an Cloud-Produkten einbinden und darauf zugreifen und einfacher auf neuere Sprachversionen upgraden. Die Reihe konzentriert sich zwar anfangs auf die ersten Cloud-Nutzer, vor allem auf App Engine-Entwickler (Standardumgebung), ist aber breit genug, um auch andere serverlose Plattformen wie Cloud Functions und Cloud Run oder andere Plattformen einzubeziehen, sofern zutreffend.
In diesem Codelab wird die Beispielanwendung aus Modul 8 zu Python 3 portiert. Außerdem wird der Datastore-Zugriff (Cloud Firestore im Datastore-Modus) von Cloud NDB auf die native Cloud Datastore-Clientbibliothek umgestellt und die Cloud Tasks-Clientbibliothek wird auf die neueste Version aktualisiert.
In Modul 7 haben wir die Verwendung der Aufgabenwarteschlange für Push-Aufgaben eingeführt und diese Verwendung in Modul 8 zu Cloud Tasks migriert. In Modul 9 geht es mit Python 3 und Cloud Datastore weiter. Nutzer, die Aufgabenwarteschlangen für Pull-Aufgaben verwenden, migrieren zu Cloud Pub/Sub und sollten stattdessen die Module 18–19 lesen.
Lerninhalte
- Beispielanwendung aus Modul 8 zu Python 3 portieren
- Datastore-Zugriff von Cloud NDB auf Cloud Datastore-Clientbibliotheken umstellen
- Auf die neueste Version der Cloud Tasks-Clientbibliothek aktualisieren
Voraussetzungen
- Ein Google Cloud Platform-Projekt mit einem aktiven GCP-Rechnungskonto
- Grundlegende Python-Kenntnisse
- Grundkenntnisse zu gängigen Linux-Befehlen
- Grundlegende Kenntnisse zur Entwicklung und Bereitstellung von App Engine-Anwendungen
- Eine funktionierende App Engine-App aus Modul 8: Führen Sie das Codelab zu Modul 8 aus (empfohlen) oder kopieren Sie die App aus Modul 8 aus dem Repository.
Umfrage
Wie werden Sie diese Anleitung verwenden?
Wie würden Sie Ihre Erfahrung mit Python bewerten?
Wie würden Sie Ihre Erfahrungen mit Google Cloud-Diensten bewerten?
2. Hintergrund
Im Modul 7 wird gezeigt, wie Sie Push-Aufgaben der App Engine-Aufgabenwarteschlange in Python 2 Flask App Engine-Anwendungen verwenden. In Modul 8 migrieren Sie diese App von Task Queue zu Cloud Tasks. In Modul 9 setzen Sie diese Reise fort und portieren die App zu Python 3. Außerdem stellen Sie den Datastore-Zugriff von Cloud NDB auf die native Clientbibliothek Cloud Datastore um.
Da Cloud NDB sowohl für Python 2 als auch für Python 3 funktioniert, reicht es für App Engine-Nutzer aus, die ihre Anwendungen von Python 2 zu Python 3 portieren. Eine zusätzliche Migration von Clientbibliotheken zu Cloud Datastore ist völlig optional. Es gibt nur einen Grund, sie in Betracht zu ziehen: Sie haben Nicht-App Engine-Anwendungen (und/oder Python 3-App Engine-Anwendungen), die bereits die Cloud Datastore-Clientbibliothek verwenden, und möchten Ihren Code so konsolidieren, dass Sie mit nur einer Clientbibliothek auf Datastore zugreifen. Cloud NDB wurde speziell für Python 2-App Engine-Entwickler als Python 3-Migrationstool entwickelt. Wenn Sie also noch keinen Code haben, der die Cloud Datastore-Clientbibliothek verwendet, müssen Sie diese Migration nicht in Betracht ziehen.
Die Entwicklung der Cloud Tasks-Clientbibliothek wird nur in Python 3 fortgesetzt. Wir migrieren also von einer der letzten Python 2-Versionen zur entsprechenden Python 3-Version. Glücklicherweise gibt es keine grundlegenden Änderungen gegenüber Python 2, sodass Sie hier nichts weiter tun müssen.
Diese Anleitung umfasst die folgenden Schritte:
- Einrichtung/Vorbereitung
- Konfiguration aktualisieren
- Anwendungscode ändern
3. Einrichtung/Vorbereitung
In diesem Abschnitt wird Folgendes erläutert:
- Cloud-Projekt einrichten
- Beispiel-App für die Baseline abrufen
- Ausgangsanwendung (neu) bereitstellen und validieren
Mit diesen Schritten stellen Sie sicher, dass Sie mit funktionierendem Code beginnen und dass dieser für die Migration zu Cloud-Diensten bereit ist.
1. Projekt einrichten
Wenn Sie das Codelab zu Modul 8 abgeschlossen haben, können Sie dasselbe Projekt (und denselben Code) wiederverwenden. Alternativ können Sie ein neues Projekt erstellen oder ein anderes vorhandenes Projekt wiederverwenden. Prüfen Sie, ob das Projekt ein aktives Abrechnungskonto und eine aktivierte App Engine-Anwendung hat. Suchen Sie die Projekt-ID, da Sie sie in diesem Codelab benötigen. Verwenden Sie sie immer, wenn Sie auf die Variable PROJECT_ID stoßen.
2. Beispiel-App für die Baseline abrufen
Eine der Voraussetzungen ist eine funktionierende App Engine-App aus Modul 8. Sie können das Codelab zu Modul 8 durcharbeiten (empfohlen) oder die App aus Modul 8 aus dem Repository kopieren. Unabhängig davon, ob Sie Ihren oder unseren Code verwenden, beginnen wir mit dem Code aus Modul 8 („START“). In diesem Codelab wird die Migration beschrieben. Am Ende steht Code, der dem im Repo-Ordner „Module 9“ („FINISH“) ähnelt.
- START: Modul 8-Repository
- ABSCHLUSS: Modul 9-Repository
- Gesamtes Repository (klonen oder ZIP-Datei herunterladen)
Unabhängig davon, welche App aus Modul 7 Sie verwenden, sollte der Ordner so aussehen wie unten, möglicherweise auch mit einem Ordner lib:
$ ls README.md appengine_config.py requirements.txt app.yaml main.py templates
3. Ausgangsanwendung (neu) bereitstellen und validieren
Führen Sie die folgenden Schritte aus, um die App aus Modul 8 bereitzustellen:
- Löschen Sie den Ordner
lib, falls er vorhanden ist, und führen Siepip install -t lib -r requirements.txtaus, umlibneu zu füllen. Möglicherweise müssen Siepip2verwenden, wenn sowohl Python 2 als auch Python 3 auf Ihrem Entwicklungscomputer installiert sind. - Achten Sie darauf, dass Sie das
gcloud-Befehlszeilentool installiert und initialisiert haben und sich mit der Verwendung vertraut gemacht haben. - Optional: Legen Sie Ihr Cloud-Projekt mit
gcloud config set projectPROJECT_IDfest, wenn SiePROJECT_IDnicht bei jedemgcloud-Befehl eingeben möchten. - Beispiel-App mit
gcloud app deploybereitstellen - Prüfen Sie, ob die App wie erwartet und ohne Probleme ausgeführt wird. Wenn Sie das Codelab für Modul 8 abgeschlossen haben, werden in der App die wichtigsten Besucher und die letzten Besuche angezeigt (siehe Abbildung unten). Unten sehen Sie die älteren Aufgaben, die gelöscht werden.

4. Konfiguration aktualisieren
requirements.txt
Die neue requirements.txt ist fast identisch mit der für Modul 8. Es gibt nur eine große Änderung: Ersetzen Sie google-cloud-ndb durch google-cloud-datastore. Nehmen Sie diese Änderung vor, damit Ihre requirements.txt-Datei so aussieht:
flask
google-cloud-datastore
google-cloud-tasks
Diese requirements.txt-Datei enthält keine Versionsnummern. Daher sind die neuesten Versionen ausgewählt. Sollten Inkompatibilitäten auftreten, ist es üblich, Versionsnummern zu verwenden, um funktionierende Versionen für eine App festzulegen.
app.yaml
Die App Engine-Laufzeit der zweiten Generation unterstützt weder integrierte Drittanbieterbibliotheken wie in Version 2.x noch das Kopieren von nicht integrierten Bibliotheken. Die einzige Anforderung für Drittanbieterpakete ist, dass sie in requirements.txt aufgeführt werden. Daher kann der gesamte Abschnitt libraries von app.yaml gelöscht werden.
Außerdem erfordert die Python 3-Laufzeit die Verwendung von Web-Frameworks, die ihr eigenes Routing durchführen. Daher müssen alle Skript-Handler in auto geändert werden. Da jedoch alle Routen in auto geändert werden müssen und keine statischen Dateien von dieser Beispiel-App bereitgestellt werden, sind beliebige Handler irrelevant. Entfernen Sie daher auch den gesamten handlers-Abschnitt.
In app.yaml muss nur die Laufzeit auf eine unterstützte Version von Python 3, z. B. 3.10, festgelegt werden. Nehmen Sie diese Änderung vor, damit die neue, abgekürzte app.yaml nur diese eine Zeile umfasst:
runtime: python310
appengine_config.py und lib löschen
Bei App Engine-Laufzeiten der nächsten Generation wird die Verwendung von Drittanbieterpaketen überarbeitet:
- Integrierte Bibliotheken sind Bibliotheken, die von Google geprüft und auf App Engine-Servern verfügbar gemacht wurden, wahrscheinlich weil sie C/C++-Code enthalten, den Entwickler nicht in der Cloud bereitstellen dürfen. Diese Bibliotheken sind in den Laufzeitumgebungen der 2. Generation nicht mehr verfügbar.
- Das Kopieren von nicht integrierten Bibliotheken (manchmal auch als „Vendoring“ oder „Self-Bundling“ bezeichnet) ist in Laufzeiten der 2. Generation nicht mehr erforderlich. Stattdessen sollten sie in
requirements.txtaufgeführt werden, wo das Build-System sie bei der Bereitstellung automatisch für Sie installiert.
Aufgrund dieser Änderungen an der Verwaltung von Drittanbieterpaketen sind weder die Datei appengine_config.py noch der Ordner lib erforderlich. Löschen Sie sie daher. In Laufzeiten der zweiten Generation installiert App Engine automatisch Drittanbieterpakete, die in requirements.txt aufgeführt sind. Zusammenfassen:
- Keine selbst gebündelten oder kopierten Bibliotheken von Drittanbietern; listen Sie sie in
requirements.txtauf. - Kein
pip installin einemlib-Ordner, d. h. keinlib-Ordnerzeitraum - Keine integrierten Drittanbieterbibliotheken in
app.yaml(daher keinlibraries-Abschnitt); Liste inrequirements.txt - Wenn Sie keine Drittanbieterbibliotheken in Ihrer App referenzieren, benötigen Sie keine
appengine_config.py-Datei.
Die einzige Anforderung für Entwickler besteht darin, alle gewünschten Drittanbieterbibliotheken in requirements.txt aufzulisten.
5. Anwendungsdateien aktualisieren
Es gibt nur eine Anwendungsdatei, main.py. Alle Änderungen in diesem Abschnitt wirken sich also nur auf diese Datei aus. Unten sehen Sie eine Darstellung der Änderungen, die erforderlich sind, um den vorhandenen Code in die neue App zu refaktorieren. Es wird nicht erwartet, dass Sie den Code Zeile für Zeile lesen. Er soll lediglich einen Überblick darüber geben, was bei dieser Refaktorierung erforderlich ist. Sie können ihn aber auch in einem neuen Tab öffnen oder herunterladen und vergrößern, wenn Sie möchten.

Importe und Initialisierung aktualisieren
Im Importabschnitt in main.py für Modul 8 werden Cloud NDB und Cloud Tasks verwendet. Er sollte so aussehen:
VORHER:
from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, tasks
app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()
Das Logging in Laufzeiten der zweiten Generation wie Python 3 ist einfacher und leistungsfähiger:
- Für umfassende Logging-Funktionen verwenden Sie Cloud Logging.
- Für die einfache Protokollierung senden Sie einfach über
print()anstdout(oderstderr). - Das Python-Modul
loggingmuss nicht verwendet werden. Entfernen Sie es.
Löschen Sie daher den Import von logging und tauschen Sie google.cloud.ndb durch google.cloud.datastore aus. Ändern Sie ds_client so, dass es auf einen Datastore-Client anstelle eines NDB-Clients verweist. Nachdem Sie diese Änderungen vorgenommen haben, sieht der Anfang Ihrer neuen App so aus:
DANACH:
from datetime import datetime
import json
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import datastore, tasks
app = Flask(__name__)
ds_client = datastore.Client()
ts_client = tasks.CloudTasksClient()
Zu Cloud Datastore migrieren
Jetzt ist es an der Zeit, die Verwendung der NDB-Clientbibliothek durch Datastore zu ersetzen. Sowohl App Engine NDB als auch Cloud NDB erfordern ein Datenmodell (Klasse). Für diese App ist es Visit. Die Funktion store_visit() funktioniert in allen anderen Migrationsmodulen gleich: Sie registriert einen Besuch, indem sie einen neuen Visit-Datensatz erstellt und die IP-Adresse und den User-Agent (Browsertyp) des besuchenden Clients speichert.
VORHER:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
Cloud Datastore verwendet jedoch keine Datenmodellklasse. Löschen Sie die Klasse. Außerdem wird in Cloud Datastore beim Erstellen von Datensätzen nicht automatisch ein Zeitstempel erstellt. Sie müssen dies manuell mit dem datetime.now()-Aufruf erledigen.
Ohne die Datenklasse sollte Ihr geändertes store_visit() so aussehen:
DANACH:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
Die Hauptfunktion ist fetch_visits(). Es wird nicht nur die ursprüngliche Anfrage für die neuesten Visit ausgeführt, sondern auch der Zeitstempel des letzten angezeigten Visit abgerufen und die Push-Aufgabe erstellt, die /trim (und damit trim()) aufruft, um die alten Visit massenhaft zu löschen. Hier sehen Sie, wie das mit Cloud NDB aussieht:
VORHER:
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
with ds_client.context():
data = Visit.query().order(-Visit.timestamp).fetch(limit)
oldest = time.mktime(data[-1].timestamp.timetuple())
oldest_str = time.ctime(oldest)
logging.info('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
ts_client.create_task(parent=QUEUE_PATH, task=task)
return (v.to_dict() for v in data), oldest_str
Die wichtigsten Änderungen:
- Ersetzen Sie die Cloud NDB-Abfrage durch das Cloud Datastore-Äquivalent. Die Abfragestile unterscheiden sich geringfügig.
- Für Datastore ist kein Kontextmanager erforderlich und Sie müssen die Daten nicht wie bei Cloud NDB mit
to_dict()extrahieren. - Protokollierungsaufrufe durch
print()ersetzen
Nach diesen Änderungen sieht fetch_visits() so aus:
DANACH:
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
visits = list(query.fetch(limit=limit))
oldest = time.mktime(visits[-1]['timestamp'].timetuple())
oldest_str = time.ctime(oldest)
print('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
Normalerweise ist das alles, was erforderlich ist. Leider gibt es ein großes Problem.
(Möglicherweise) Neue (Push-)Warteschlange erstellen
In Modul 7 haben wir die Verwendung von App Engine taskqueue in die vorhandene App aus Modul 1 eingefügt. Ein wichtiger Vorteil von Push-Aufgaben als Legacy-App Engine-Funktion ist, dass automatisch eine „Standard“-Warteschlange erstellt wird. Als diese App in Modul 8 zu Cloud Tasks migriert wurde, war die Standardwarteschlange bereits vorhanden. Wir mussten uns also damals noch nicht darum kümmern. Das ändert sich hier in Modul 9.
Ein wichtiger Aspekt ist, dass die neue App Engine-Anwendung keine App Engine-Dienste mehr verwendet. Daher können Sie nicht mehr davon ausgehen, dass App Engine automatisch eine Aufgabenwarteschlange in einem anderen Produkt (Cloud Tasks) erstellt. Wenn Sie eine Aufgabe in fetch_visits() erstellen, schlägt dies fehl, da die Warteschlange nicht vorhanden ist. Es ist eine neue Funktion erforderlich, um zu prüfen, ob die Warteschlange („default“) vorhanden ist. Falls nicht, muss sie erstellt werden.
Nennen Sie diese Funktion _create_queue_if() und fügen Sie sie in Ihre Anwendung direkt über fetch_visits() ein, da sie dort aufgerufen wird. Der Text der hinzuzufügenden Funktion:
def _create_queue_if():
'app-internal function creating default queue if it does not exist'
try:
ts_client.get_queue(name=QUEUE_PATH)
except Exception as e:
if 'does not exist' in str(e):
ts_client.create_queue(parent=PATH_PREFIX,
queue={'name': QUEUE_PATH})
return True
Für die Cloud Tasks-Funktion create_queue() ist der vollständige Pfadname der Warteschlange mit Ausnahme des Warteschlangennamens erforderlich. Erstellen Sie zur Vereinfachung eine weitere Variable PATH_PREFIX, die QUEUE_PATH minus den Warteschlangennamen (QUEUE_PATH.rsplit('/', 2)[0]) darstellt. Fügen Sie die Definition oben ein, sodass der Codeblock mit allen konstanten Zuweisungen so aussieht:
_, PROJECT_ID = google.auth.default()
REGION_ID = 'REGION_ID' # replace w/your own
QUEUE_NAME = 'default' # replace w/your own
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION_ID, QUEUE_NAME)
PATH_PREFIX = QUEUE_PATH.rsplit('/', 2)[0]
Ändern Sie nun die letzte Zeile in fetch_visits(), um _create_queue_if() zu verwenden. Erstellen Sie dazu zuerst die Warteschlange, falls erforderlich, und erstellen Sie dann die Aufgabe:
if _create_queue_if():
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
Sowohl _create_queue_if() als auch fetch_visits() sollten jetzt insgesamt so aussehen:
def _create_queue_if():
'app-internal function creating default queue if it does not exist'
try:
ts_client.get_queue(name=QUEUE_PATH)
except Exception as e:
if 'does not exist' in str(e):
ts_client.create_queue(parent=PATH_PREFIX,
queue={'name': QUEUE_PATH})
return True
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
visits = list(query.fetch(limit=limit))
oldest = time.mktime(visits[-1]['timestamp'].timetuple())
oldest_str = time.ctime(oldest)
print('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
if _create_queue_if():
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
Abgesehen von diesem zusätzlichen Code ist der restliche Cloud Tasks-Code aus Modul 8 größtenteils unverändert. Der letzte Codeabschnitt, den wir uns ansehen, ist der Aufgaben-Handler.
Aufgaben-Handler für Updates (Push)
Im Task-Handler trim() werden mit dem Cloud NDB-Code Besuche abgefragt, die älter als die ältesten angezeigten sind. Dabei wird eine ausschließlich schlüsselbasierte Abfrage verwendet, um die Verarbeitung zu beschleunigen. Warum sollten alle Daten abgerufen werden, wenn nur die Besuchs-IDs benötigt werden? Wenn Sie alle Besuchs-IDs haben, löschen Sie sie alle in einem Batch mit der Funktion delete_multi() von Cloud NDB.
VORHER:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = float(request.get_json().get('oldest'))
with ds_client.context():
keys = Visit.query(
Visit.timestamp < datetime.fromtimestamp(oldest)
).fetch(keys_only=True)
nkeys = len(keys)
if nkeys:
logging.info('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id()) for k in keys)))
ndb.delete_multi(keys)
else:
logging.info(
'No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
Wie bei fetch_visits() besteht der Großteil der Änderungen darin, Cloud NDB-Code durch Cloud Datastore zu ersetzen, die Abfragestile anzupassen, die Verwendung des Kontextmanagers zu entfernen und die Logging-Aufrufe in print() zu ändern.
DANACH:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = float(request.get_json().get('oldest'))
query = ds_client.query(kind='Visit')
query.add_filter('timestamp', '<', datetime.fromtimestamp(oldest))
query.keys_only()
keys = list(visit.key for visit in query.fetch())
nkeys = len(keys)
if nkeys:
print('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id) for k in keys)))
ds_client.delete_multi(keys)
else:
print('No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
Am Hauptanwendungs-Handler root() ändert sich nichts.
Zu Python 3 portieren
Diese Beispiel-App wurde so konzipiert, dass sie sowohl mit Python 2 als auch mit Python 3 ausgeführt werden kann. Alle Python 3-spezifischen Änderungen wurden bereits in den entsprechenden Abschnitten dieser Anleitung behandelt. Es sind keine zusätzlichen Schritte oder Kompatibilitätsbibliotheken erforderlich.
Cloud Tasks-Update
Die letzte Version der Cloud Tasks-Clientbibliothek, die Python 2 unterstützt, ist 1.5.0. Zum Zeitpunkt der Erstellung dieses Dokuments ist die aktuelle Version der Clientbibliothek für Python 3 vollständig mit dieser Version kompatibel. Es sind also keine weiteren Updates erforderlich.
Aktualisierung der HTML-Vorlage
Auch in der HTML-Vorlagendatei templates/index.html sind keine Änderungen erforderlich. Damit sind alle notwendigen Änderungen abgeschlossen, um die App aus Modul 9 zu erhalten.
6. Zusammenfassung/Bereinigung
Anwendung bereitstellen und überprüfen
Nachdem Sie die Code-Updates, insbesondere die Portierung zu Python 3, abgeschlossen haben, stellen Sie Ihre App mit gcloud app deploy bereit. Die Ausgabe sollte mit der der Apps aus Modul 7 und 8 identisch sein, mit der Ausnahme, dass Sie den Datenbankzugriff in die Cloud Datastore-Clientbibliothek verschoben und auf Python 3 aktualisiert haben:

Damit ist das Codelab abgeschlossen. Vergleichen Sie Ihren Code mit dem Code im Ordner „Modul 9“. Glückwunsch!
Bereinigen
Allgemein
Wenn Sie die App vorerst nicht mehr benötigen, empfehlen wir Ihnen, sie zu deaktivieren, um Abrechnungen zu vermeiden. Wenn Sie jedoch weitere Tests durchführen möchten, bietet die App Engine-Plattform ein kostenloses Kontingent. Solange Sie diese Nutzungsebene nicht überschreiten, werden Ihnen keine Gebühren berechnet. Das gilt für die Rechenleistung. Es können aber auch Gebühren für relevante App Engine-Dienste anfallen. Weitere Informationen finden Sie auf der Preisseite. Wenn bei dieser Migration andere Cloud-Dienste beteiligt sind, werden diese separat abgerechnet. Sehen Sie sich in beiden Fällen gegebenenfalls den Abschnitt „Spezifisch für dieses Codelab“ unten an.
Die Bereitstellung auf einer serverlosen Google Cloud-Compute-Plattform wie App Engine verursacht geringe Build- und Speicherkosten. Cloud Build und Cloud Storage haben jeweils ein eigenes kostenloses Kontingent. Das Speichern dieses Bildes verbraucht einen Teil dieses Kontingents. Möglicherweise leben Sie jedoch in einer Region, in der es kein solches kostenloses Kontingent gibt. Achten Sie daher auf Ihre Speichernutzung, um potenzielle Kosten zu minimieren. Folgende Cloud Storage-„Ordner“ sollten Sie sich ansehen:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Die oben genannten Speicherlinks hängen von Ihrem
PROJECT_IDund *LOC*ab, z. B. „us“, wenn Ihre App in den USA gehostet wird.
Wenn Sie diese Anwendung oder andere zugehörige Migrations-Codelabs nicht weiter verwenden und alles vollständig löschen möchten, beenden Sie Ihr Projekt.
Spezifisch für dieses Codelab
Die unten aufgeführten Dienste sind nur für dieses Codelab verfügbar. Weitere Informationen finden Sie in der Dokumentation der einzelnen Produkte:
- Für Cloud Tasks gibt es eine kostenlose Stufe. Weitere Informationen finden Sie auf der Preisseite.
- Der Dienst App Engine Datastore wird von Cloud Datastore (Cloud Firestore im Datastore-Modus) bereitgestellt, das ebenfalls eine kostenlose Stufe bietet. Weitere Informationen finden Sie auf der Preisseite.
Nächste Schritte
Damit ist die Migration von App Engine Task Queue-Push-Aufgaben zu Cloud Tasks abgeschlossen. Die optionale Migration von Cloud NDB zu Cloud Datastore wird auch separat (ohne Task Queue oder Cloud Tasks) in Modul 3 behandelt. Neben Modul 3 gibt es weitere Migrationsmodule, die sich mit der Umstellung von gebündelten App Engine-Legacy-Diensten befassen:
- Modul 2: Von App Engine NDB zu Cloud NDB migrieren
- Modul 3: Von Cloud NDB zu Cloud Datastore migrieren
- Module 12–13: Von App Engine Memcache zu Cloud Memorystore migrieren
- Module 15–16: Migration von App Engine Blobstore zu Cloud Storage
- Module 18–19: App Engine Task Queue (Pull-Aufgaben) zu Cloud Pub/Sub
App Engine ist nicht mehr die einzige serverlose Plattform in Google Cloud. Wenn Sie eine kleine App Engine-Anwendung oder eine Anwendung mit eingeschränkter Funktionalität haben und sie in einen eigenständigen Mikrodienst umwandeln möchten oder eine monolithische Anwendung in mehrere wiederverwendbare Komponenten aufteilen möchten, sind dies gute Gründe für einen Wechsel zu Cloud Functions. Wenn die Containerisierung Teil Ihres Anwendungsentwicklungs-Workflows geworden ist, insbesondere wenn er aus einer CI/CD-Pipeline (Continuous Integration/Continuous Delivery oder Deployment) besteht, sollten Sie eine Migration zu Cloud Run in Betracht ziehen. Diese Szenarien werden in den folgenden Modulen behandelt:
- Von App Engine zu Cloud Functions migrieren: Modul 11
- Von App Engine zu Cloud Run migrieren: Modul 4 enthält Informationen zum Containerisieren Ihrer App mit Docker und Modul 5 zum Containerisieren ohne Container, Docker-Kenntnisse oder
Dockerfiles.
Der Wechsel zu einer anderen serverlosen Plattform ist optional. Wir empfehlen, die besten Optionen für Ihre Apps und Anwendungsfälle zu prüfen, bevor Sie Änderungen vornehmen.
Unabhängig davon, welches Migrationsmodul Sie als Nächstes in Betracht ziehen, können Sie auf alle Serverless Migration Station-Inhalte (Codelabs, Videos, Quellcode [sofern verfügbar]) über das zugehörige Open-Source-Repository zugreifen. Das README des Repositorys enthält auch Informationen dazu, welche Migrationen infrage kommen und welche Reihenfolge der Migrationsmodule relevant ist.
7. Zusätzliche Ressourcen
Probleme mit Codelabs/Feedback
Wenn Sie Probleme mit diesem Codelab feststellen, suchen Sie bitte zuerst nach Ihrem Problem, bevor Sie es melden. Links zum Suchen und Erstellen neuer Probleme:
Migrationsressourcen
Links zu den Repository-Ordnern für Modul 8 (START) und Modul 9 (FINISH) finden Sie in der Tabelle unten. Sie können auch über das Repository für alle App Engine-Codelab-Migrationen auf sie zugreifen. Sie können es klonen oder eine ZIP-Datei herunterladen.
Codelab | Python 2 | Python 3 |
(n/a) | ||
Modul 9 | (n/a) |
Onlineressourcen
Unten finden Sie Online-Ressourcen, die für diese Anleitung relevant sein könnten:
App Engine
- App Engine-Dokumentation
- Python 2-Laufzeit für die App Engine-Standardumgebung
- Python 3-Laufzeit für die App Engine-Standardumgebung
- Unterschiede zwischen den Python 2- und Python 3-Laufzeiten in App Engine (Standardumgebung)
- Migrationsanleitung für App Engine (Standardumgebung) von Python 2 zu Python 3
- Informationen zu Preisen und Kontingenten für App Engine
Cloud NDB
Cloud Datastore
- Google Cloud Datastore-Dokumentation
- Google Cloud Datastore-Repository
- Cloud Datastore-Preisinformationen
Cloud Tasks
Andere Cloud-Informationen
- Python auf der Google Cloud Platform
- Google Cloud Python-Clientbibliotheken
- Kostenlose Stufe von Google Cloud
- Google Cloud SDK (
gcloud-Befehlszeilentool) - Gesamte Google Cloud-Dokumentation
Lizenz
Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.