Modul 6: Von Cloud Datastore zu Cloud Firestore migrieren

1. Übersicht

Diese Reihe von Codelabs – also praxisorientierten Anleitungen zum selbstbestimmten Lernen – soll Entwickler von Google App Engine (Standard) bei der Modernisierung ihrer Anwendungen unterstützen, indem sie sie durch eine Reihe von Migrationen führen. Die meisten dieser Migrationen erfordern die Abkehr von ursprünglich gebündelten Laufzeitdiensten, da die Laufzeiten der nächsten Generation flexibler sind und den Nutzern eine größere Vielfalt an Dienstoptionen bieten. Eine weitere Möglichkeit zur Modernisierung einer App ist das Upgrade auf ein neueres Produkt. Das ist das Thema dieses Codelabs.

App Engine-Nutzer, die über die Cloud NDB- oder Cloud Datastore-Clientbibliotheken auf Datastore zugreifen, sind einsatzbereit und müssen nicht weiter migriert werden. Cloud Firestore ist jedoch der neueste, skalierbare, hochverfügbare NoSQL-Datenspeicher mit Funktionen aus der Firebase-Echtzeitdatenbank.

Wenn Sie als Entwickler die Funktionen von Firestore nutzen möchten oder zumindest ein ausreichendes Interesse an der Migration haben, sind Sie hier richtig. In dieser Anleitung erfahren Sie, wie Sie eine App Engine-Anwendung mithilfe von Cloud Datastore zu Cloud Firestore migrieren.

Du lernst, wie du

  • Unterschiede zwischen Datastore und Firestore erkennen
  • Von Cloud Datastore zu Cloud Firestore migrieren

Voraussetzungen

Umfrage

Wie möchten Sie dieses Codelab nutzen?

<ph type="x-smartling-placeholder"></ph> Lesen Sie sie nur durch. Lies sie dir durch und absolviere die Übungen

2. Hintergrund

Datastore von App Engine wurde 2013 als eigenes Produkt – Google Cloud Datastore – und ist jetzt für Entwickler außerhalb von App Engine zugänglich. Im folgenden Jahr wurde Firebase von Google übernommen. Damals war es für seine Echtzeitdatenbank bekannt.

In den nächsten Jahren haben die Firebase- und Cloud Datastore-Teams an der Integration einiger Firebase-Funktionen in Datastore gearbeitet. Daher wurde 2017 die nächste Generation von Cloud Datastore veröffentlicht. Um die Übernahme einiger Firebase-Funktionen widerzuspiegeln, wurde es in Cloud Firestore umbenannt.

Cloud Firestore wurde zum standardmäßigen NoSQL-Speichermechanismus für Google Cloud-Projekte. Neue Anwendungen können Cloud Firestore nativ verwenden, während vorhandene Datastore-Datenbanken im Hintergrund zu Firestore konvertiert wurden und jetzt als „Firestore im Datastore-Modus“ funktionieren. um die Kompatibilität mit Datastore-Vorgängen zu wahren. Daher können Anwendungen Cloud Firestore nur in einem dieser Modi ausführen und können nach dem Festlegen nicht mehr geändert werden.

Wenn Nutzer derzeit neue Projekte erstellen und eine NoSQL-Lösung auswählen, werden sie entweder aufgefordert, entweder Firestore im Datastore-Modus oder Firestore im nativen Modus auszuwählen. Sobald Nutzer Datastore-Entitäten hinzufügen, können sie nicht mehr zu Firestore wechseln. Ebenso können sie nicht mehr zu Datastore (bzw. zu Firestore im Datastore-Modus) zurück, sobald der native Firestore-Modus ausgewählt ist. Weitere Informationen finden Sie in der Dokumentation auf der Seite Cloud Firestore im Datastore-Modus oder nativen Firestore-Modus auswählen. Damit eine Anwendung zu Firestore migriert werden kann, muss ein neues Projekt erstellt, Datastore exportiert und dann in Firestore importiert werden. Diese Anleitung soll Entwicklern eine Vorstellung von den Unterschieden zwischen der Verwendung von Cloud Datastore und Cloud Firestore vermitteln.

Diese Migration wird von den Nutzern nicht erwartet. Deshalb ist sie optional. Die native Verwendung von Cloud Firestore hat zwar offensichtliche Vorteile, z. B. die Clientauthentifizierung, die Einbindung von Firebase-Regeln und natürlich die Firebase-Echtzeitdatenbank, aber die Migrationsschritte sind „unkompliziert“:

  • Sie müssen ein anderes Projekt als das Projekt Ihrer aktuellen App verwenden.
  • Ein Projekt, dem eine Anwendung Datastore-Entitäten hinzugefügt hat, kann nicht im nativen Modus zu Firestore gewechselt werden.
  • Ebenso kann ein Projekt, bei dem Firestore im nativen Modus ausgewählt wurde, nicht auf Firestore im Datastore-Modus zurückgesetzt werden.
  • Es gibt kein Migrationstool, das Daten von einem Projekt in ein anderes streamen kann.
  • Einige wichtige Datastore-Features wie Namespaces und ein höherer Schreibdurchsatz (> 10.000/s) sind in Firestore nicht verfügbar.
  • Die Export- und Importtools sind "privilegiert". und „all or none“ (alle oder nichts) Szenarien durchführen.
    • Wenn Ihre Anwendung viele Datastore-Entitäten enthält, kann der Export und Import in Firestore viele Stunden dauern.
    • Während dieser Zeit kann Ihre Anwendung oder Ihr Dienst keine Daten schreiben oder aktualisieren.
    • Migrationsaktivitäten werden auf die normale Nutzung angerechnet. können Sie es (wenn möglich auf Tageskontingente) verteilen, um die Kosten zu minimieren.
    • Da der neue Dienst in einem anderen Projekt ausgeführt wird, benötigen Sie ein Fenster, in dem die DNS-Updates weitergegeben werden.
  • Datastore und Firestore haben ähnliche, aber unterschiedliche Datenmodelle, sodass bei der Migration die Funktionsweise der Anwendung/des Dienstes aktualisiert werden muss.
    • Ancestor-Abfragen aus Datastore sind jetzt Firestore-Sammlungsabfragen (Standardeinstellung).
    • Allgemeine Abfragen aus Datastore sind Firestore-Sammlungsgruppenabfragen.
    • Indizes und Verarbeitung unterscheiden sich usw.

Wenn Sie also eine relativ einfache Anwendung für die Migration in Betracht ziehen, sich auf die Simulation einer solchen Migration vorbereiten oder einfach hier mehr über Datastore im Vergleich zu Firestore erfahren möchten, fahren Sie bitte fort.

Python 2-Nutzer:Dieses optionale Codelab für die Migration wird nur in Python 3 vorgestellt. Da Cloud Firestore auch 2.x unterstützt, können Nutzer die Nutzungsunterschiede interpolieren. Ein Beispiel ist, dass Firestore-Einträge Unicode-Strings (anstelle von Bytestrings) verwenden. Daher ist für Python 2-Stringliterale ein u''-Leitindikator erforderlich. Das bedeutet, dass eine 2.x-store_visit()-Funktion so aussieht:

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),
    })

Davon abgesehen sollte die Clientbibliothek ähnlich funktionieren. Das einzige andere Problem, das berücksichtigt werden muss, ist, dass die 2.x-Cloud Firestore-Bibliothek „eingefroren“ ist. Im Hinblick auf die Entwicklung werden immer mehr/neuere Funktionen nur in der Firestore-3.x-Clientbibliothek verfügbar sein.

Im Anschluss an diese Migration sind dies die wichtigsten Schritte dieser Anleitung:

  1. Einrichtung/Vorarbeit
  2. Cloud Firestore-Bibliothek hinzufügen
  3. Anwendungsdateien aktualisieren

3. Einrichtung/Vorarbeit

Bevor wir mit dem Hauptteil des Tutorials fortfahren, richten wir unser Projekt ein, rufen den Code ab und stellen dann die Referenzanwendung bereit, damit wir wissen, dass wir mit funktionierendem Code beginnen.

1. Projekt einrichten

Wir empfehlen, dasselbe Projekt aus dem Codelab für Modul 3 zu verwenden. Alternativ können Sie ein ganz neues Projekt erstellen oder ein anderes vorhandenes Projekt wiederverwenden. Achten Sie darauf, dass das Projekt ein aktives Rechnungskonto hat und die App Engine (App) aktiviert ist.

2. Baseline-Beispiel-App abrufen

Eine der Voraussetzungen für dieses Codelab ist eine funktionierende Beispiel-App für Modul 3. Wenn Sie kein Google Ads-Konto haben, schließen Sie die Anleitung für Modul 3 (Link oben) ab, bevor Sie fortfahren. Falls Sie bereits mit dem Inhalt vertraut sind, können Sie einfach damit beginnen, indem Sie sich den Code des Moduls 3 unten holen.

Unabhängig davon, ob Sie Ihren oder unseren verwenden, beginnen wir mit dem Code für Modul 3. Dieses Codelab für Modul 6 führt Sie durch die einzelnen Schritte. Wenn Sie fertig sind, sollte es dem Code am FINISH-Punkt ähneln. (Diese Anleitung ist nur für Python 3 verfügbar.)

Das Verzeichnis der Dateien in Modul 3 (Ihre oder unsere) sollte so aussehen:

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

3. Modul 3 App (erneut) bereitstellen

Sie müssen die verbleibenden Schritte jetzt ausführen:

  1. Machen Sie sich noch einmal mit dem gcloud-Befehlszeilentool vertraut (falls erforderlich).
  2. Code aus Modul 3 (falls erforderlich) in App Engine (noch einmal) bereitstellen

Nachdem Sie diese Schritte erfolgreich ausgeführt und bestätigt haben, dass der Dienst betriebsbereit ist, fahren wir mit der Anleitung fort und beginnen mit den Konfigurationsdateien.

Python 2-Anforderungen

  • Achten Sie darauf, dass app.yaml (noch) auf die gebündelten Drittanbieterpakete verweist: grpcio und setuptools.
  • Achte darauf, dass appengine_config.py weiterhin pkg_resources und google.appengine.ext.vendor verwendet, um die App auf Ressourcen von Drittanbietern zu verweisen.
  • Im nächsten Abschnitt zum Aktualisieren von requirements.txt müssen Sie google-cloud-firestore==1.9.0 verwenden, da dies die endgültige 2.x-kompatible Version der Python Firestore-Clientbibliothek ist.
    • Wenn Ihre requirements.txt einen Eintrag für google-cloud-core hat, lassen Sie diesen unverändert.
    • Lösche lib und installiere es mit pip install -t lib -r requirements.txt neu.

4. Konfigurationsdateien aktualisieren (Cloud Firestore-Bibliothek hinzufügen)

Über die Einrichtung hinaus sind die nächsten Schritte erforderlich, die Konfiguration und anschließend die Anwendungsdateien zu aktualisieren. Bei der ersten Variante ist die einzige Konfigurationsänderung ein kleinerer Paketaustausch in der Datei requirements.txt.

Ersetzen Sie die Zeile google-cloud-datastore in requirements.txt durch google-cloud-firestore, sodass das so aussieht:

Flask==1.1.2
google-cloud-firestore==2.0.2

Wir empfehlen, jeweils die neueste Version jeder Bibliothek zu verwenden. Die oben angegebenen Versionsnummern sind zum Zeitpunkt der Veröffentlichung dieses Dokuments die aktuelle Version. Der Code im Repository-Ordner FINISH wird häufiger aktualisiert und hat möglicherweise eine neuere Version.

Da keine weiteren Konfigurationsänderungen vorgenommen werden, bleiben app.yaml und templates/index.html unverändert.

5. Anwendungsdateien aktualisieren

Es gibt nur die Anwendungsdatei main.py. Alle Änderungen in diesem Abschnitt wirken sich daher nur auf diese Datei aus.

1. Importe

Der Wechsel des Paketimports ist eine kleine Änderung von datastore zu firestore:

  • VORHER:
from google.cloud import datastore
  • NACHHER:
from google.cloud import firestore

2. Firestore-Zugriff

Erstellen Sie nach der Initialisierung von Flask den Firestore-Client. Nehmen Sie eine ähnliche Änderung wie oben für den Client vor:

  • VORHER:
app = Flask(__name__)
ds_client = datastore.Client()
  • NACHHER:
app = Flask(__name__)
fs_client = firestore.Client()

Durch die Migration von Cloud NDB zu Cloud Datastore haben Sie den komplizierten Weg zu Cloud Firestore bereits erledigt. Mit Datastore erstellen Sie Datensätze in Form von Entitäten, die aus gemeinsamen Properties bestehen, und gruppieren sie nach Schlüsseln. Datensätze in Firestore sind Dokumente, die aus Schlüssel/Wert-Paaren bestehen und in Sammlungen gruppiert sind. Bei der Migration von Datastore müssen Sie über diese Unterschiede nachdenken, da sie beim Erstellen von Datensätzen und beim Abfragen von Datensätzen eintreten. Ihre Ergebnisse können variieren, je nachdem, wie komplex Ihr Datastore-Code ist.

In Datastore werden Abfragen basierend auf dem Entitätstyp sowie Filter- und Sortierkriterien durchgeführt. Bei Firestore ist das Abfragen von Daten ähnlich. Sehen wir uns ein kurzes Beispiel an, bei dem folgende Abfragewerte, Clients (ds_client bzw. fs_client) und Importe angenommen werden:

from datetime import datetime
from firestore.Query import DESCENDING

OCT1 = datetime(2020, 10, 1)
LIMIT = 10

In Datastore werden die zehn neuesten Visit-Entitäten vor dem 1. Oktober 2020 in absteigender Reihenfolge abgefragt:

query = ds_client.query(kind='Visit')
query.add_filter('timestamp', '>=', datetime(2020, 10, 1))
query.order = ['-timestamp']
return query.fetch(limit=LIMIT)

Wiederholen Sie den Vorgang für Firestore über die Sammlung Visit:

query = fs_client.collection('Visit')
query.where('timestamp', '>=', datetime(2020, 10, 1))
query.order_by('timestamp', direction=DESCENDING)
return query.limit(LIMIT).stream()

Die Beispielanwendungsabfrage ist einfacher (keine WHERE-Klausel). Hier ist der Cloud Datastore-Code:

  • VORHER:
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)

Bei der Migration zu Firestore werden Sie neue Dokumente erstellen, die Entitäten ähneln, und die Abfragen wie zuvor gezeigt.

  • NACHHER:
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

Die Hauptfunktion root() bleibt dieselbe wie die Vorlagendatei index.html. Überprüfen Sie Ihre Änderungen noch einmal und speichern, bereitstellen und bestätigen Sie sie.

6. Zusammenfassung/Bereinigung

Anwendung bereitstellen

Stellen Sie die Anwendung noch einmal mit gcloud app deploy bereit und prüfen Sie, ob sie funktioniert. Ihr Code sollte jetzt mit dem Inhalt im Modul 6-Repository (oder einer 2.x-Version, falls Sie diese bevorzugen) übereinstimmen.

Wenn Sie zu dieser Reihe gesprungen sind, ohne eines der vorherigen Codelabs durchzuführen, ändert sich die App selbst nicht. Alle Besuche der Hauptwebseite (/) werden registriert. Sobald Sie die Website häufig genug besucht haben, sieht sie wie folgt aus:

Besuche App

Sie haben die optionale Migration von Modul 6 abgeschlossen. Dies ist wahrscheinlich eine der oder die letzten Migrationen, die Sie im Hinblick auf den App Engine-Datenspeicher vornehmen können. Eine alternative Migration, die Sie in Betracht ziehen können, ist die Containerisierung Ihrer Anwendung für Cloud Run, falls Sie dies noch nicht getan haben (siehe Module 4 und 5, unten verlinkte Codelabs).

Optional: Bereinigung

Wie wäre es mit einer Bereinigung, damit Ihnen erst dann Kosten in Rechnung gestellt werden, wenn Sie bereit sind, mit dem nächsten Codelab für die Migration fortzufahren? Als Entwickler sind Sie wahrscheinlich bereits über die Preisinformationen von App Engine informiert.

Optional: Anwendung deaktivieren

Wenn Sie noch nicht mit der nächsten Anleitung fortfahren möchten, deaktivieren Sie Ihre Anwendung, um Gebühren zu vermeiden. Wenn Sie bereit sind, mit dem nächsten Codelab fortzufahren, können Sie es wieder aktivieren. Auch wenn Ihre Anwendung deaktiviert ist, wird kein Traffic berechnet. Ihnen können jedoch auch Kosten für die Firestore-Nutzung in Rechnung gestellt werden, wenn sie das kostenlose Kontingent überschreitet. Löschen Sie also so viel, dass Sie unter dieses Limit fallen.

Wenn Sie andererseits nicht mit der Migration fortfahren und alles vollständig löschen möchten, können Sie Ihr Projekt herunterfahren.

Nächste Schritte

Neben dieser Anleitung gibt es verschiedene andere Codelabs für Migrationsmodul, die Sie in Betracht ziehen können:

  • Modul 7: App Engine-Push-Aufgabenwarteschlangen (erforderlich, wenn Sie [push]-Aufgabenwarteschlangen verwenden)
    • Fügt App Engine-taskqueue-Push-Aufgaben zur Anwendung in Modul 1 hinzu
    • Bereitet Nutzer auf die Migration zu Cloud Tasks in Modul 8 vor
  • Modul 4: Mit Docker zu Cloud Run migrieren
    • Anwendung containerisieren, um sie mit Docker in Cloud Run auszuführen
    • Durch diese Migration können Sie bei Python 2 bleiben.
  • Modul 5: Mit Cloud Buildpacks zu Cloud Run migrieren
    • Anwendung mit Cloud Buildpacks für die Ausführung in Cloud Run containerisieren
    • Sie müssen nichts über Docker, Container oder Dockerfiles wissen.
    • Erfordert, dass Ihre Anwendung bereits zu Python 3 migriert wurde (Buildpacks unterstützen Python 2 nicht)

7. Zusätzliche Ressourcen

Codelabs-Probleme/Feedback mit App Engine-Migrationsmodul

Wenn Sie Probleme mit diesem Codelab feststellen, suchen Sie bitte zuerst nach dem Problem, bevor Sie es einreichen. Links zum Suchen und Erstellen neuer Ausgaben:

Migrationsressourcen

Links zu den Repository-Ordnern für Modul 3 (START) und Modul 6 (FINISH) finden Sie in der folgenden Tabelle. Sie können auch über das Repository für alle App Engine-Migrationen auf sie zugreifen, das Sie klonen oder als ZIP-Datei herunterladen können.

Codelab

Python 2

Python 3

Modul 3

(Code)

code

Module 6

(nicht zutreffend)

code

App Engine-Ressourcen

Nachfolgend finden Sie zusätzliche Ressourcen zu dieser Migration: