Moduł 6. Migracja z Cloud Datastore do Cloud Firestore

1. Omówienie

Ta seria ćwiczeń z programowania (do samodzielnego ukończenia, praktycznych samouczków) ma pomóc deweloperom w modernizacji aplikacji korzystających z Google App Engine (wersja standardowa) przez przeprowadzenie serii migracji. Większość takich migracji wiąże się z odejściem od oryginalnych usług w pakiecie środowiska wykonawczego, ponieważ środowiska wykonawcze nowej generacji są bardziej elastyczne, co daje użytkownikom większą różnorodność opcji usług. Kolejnym sposobem modernizacji aplikacji jest uaktualnienie aplikacji do nowszej wersji i jest przedmiotem tego ćwiczenia z programowania.

Użytkownicy App Engine, którzy korzystają z Datastore za pomocą bibliotek klienta Cloud NDB lub Cloud Datastore, są bardzo przydatni i nie muszą przeprowadzać dalszych migracji. Jednak Cloud Firestore to najnowszy, skalowalny i o wysokiej dostępności magazyn danych NoSQL z funkcjami z bazy danych Firebase w czasie rzeczywistym.

To odpowiednie miejsce, jeśli jesteś deweloperem i chcesz używać Firestore, aby wykorzystać jej funkcje, lub masz dość chęci do poznania skutków migracji. Z tego samouczka dowiesz się, jak przenieść aplikację App Engine przy użyciu Cloud Datastore do Cloud Firestore.

Dowiesz się,

  • Rozpoznawanie różnic między Datastore a Firestore
  • Migracja z Cloud Datastore do Cloud Firestore

Czego potrzebujesz

Ankieta

Jak będziesz używać tego ćwiczenia z programowania?

tylko do przeczytania. Przeczytaj go i wykonaj ćwiczenia
.

2. Tło

Datastore w App Engine stał się własną usługą w 2013 roku, czyli Google Cloud Datastore, i jest teraz dostępny dla programistów poza App Engine. W następnym roku Google przejęła Firebase. W tamtym czasie słynęła ze swojej bazy danych działającej w czasie rzeczywistym.

W ciągu następnych kilku lat zespoły Firebase i Cloud Datastore pracowały nad integracją niektórych funkcji Firebase z Datastore. W związku z tym w 2017 roku opublikowano nową generację Cloud Datastore. Aby odzwierciedlić dziedziczenie niektórych funkcji Firebase, zmieniliśmy nazwę usługi na Cloud Firestore.

Usługa Cloud Firestore stała się domyślnym mechanizmem przechowywania danych NoSQL dla projektów Google Cloud. Nowe aplikacje mogą korzystać z Cloud Firestore natywnie, natomiast istniejące bazy danych Datastore zostały przekonwertowane na bazy danych Firestore i teraz działają jako „Firestore w trybie Datastore”. aby zachować zgodność z operacjami Datastore. W związku z tym aplikacje mogą działać w Cloud Firestore tylko w jednym z tych trybów, a ustawionych trybów nie można zmieniać.

Obecnie, gdy użytkownicy tworzą nowe projekty i wybiorą rozwiązanie NoSQL, widzą prośbę o wybranie Firestore w trybie Datastore lub Firestore w trybie natywnym. Gdy użytkownicy dodadzą encje Datastore, nie mogą przejść do Firestore. Podobnie po wybraniu trybu natywnego Firestore nie mogą oni wrócić do Datastore (a nie do Firestore w trybie Datastore). Więcej informacji znajdziesz w dokumentacji na temat wyboru między Cloud Firestore w trybie Datastore a natywnym trybem Firestore w dokumentacji. Aby przenieść aplikację do Firestore, należy utworzyć nowy projekt z Datastore, a następnie zaimportowany do Firestore. Ten samouczek przedstawia programistom różnice między używaniem Cloud Datastore i Cloud Firestore.

Tej migracji nie oczekujemy od użytkowników, dlatego jest ona opcjonalna. Bezpośrednie używanie Cloud Firestore ma oczywiste zalety, takie jak uwierzytelnianie klienta, integracja reguł Firebase i oczywiście baza danych Firebase w czasie rzeczywistym, jednak etapy migracji są „niewygodne”:

  • Musisz użyć innego projektu niż używany w bieżącej aplikacji.
  • Projektu, w którym aplikacja dodała encje Datastore, nie można przełączyć na Firestore w trybie natywnym
  • Projekt, w którym wybrano Firestore w trybie natywnym, nie może wrócić do Firestore w trybie Datastore.
  • Nie ma narzędzia do migracji, które mogłoby przesyłać strumieniowo dane z jednego projektu do innego.
  • Niektóre ważne funkcje Datastore, takie jak przestrzenie nazw i większa przepustowość zapisu (>10 KB/s), nie są dostępne w Firestore.
  • Narzędzia do eksportowania i importowania są „podstawowe” i „wszystko albo nic”, w różnych sytuacjach.
    • Jeśli Twoja aplikacja ma wiele encji Datastore, jej wyeksportowanie i zaimportowanie do Firestore może zająć wiele godzin.
    • W tym czasie Twoja aplikacja lub usługa nie będzie mogła zapisywać ani aktualizować danych.
    • Działania związane z migracją są wliczane do normalnego użytkowania. warto rozłożyć ten budżet (w miarę możliwości między limity dzienne), aby zminimalizować koszty.
    • Twoja nowa usługa działa w innym projekcie, dlatego musisz mieć okno na propagowanie aktualizacji DNS.
  • Datastore i Firestore mają podobne, ale różne modele danych, więc migracja wymaga zaktualizowania sposobu działania aplikacji/usługi.
    • Zapytania nadrzędne z Datastore są teraz zapytaniami do kolekcji Firestore (domyślnie)
    • Zapytania przybliżone z Datastore to zapytania dotyczące grup kolekcji Firestore
    • Indeksy i obsługa są różne itp.

Jeśli masz dość prostą aplikację, którą warto rozważyć migrację, przygotowujesz się do takiej migracji lub po prostu chcesz dowiedzieć się więcej o różnicach między Datastore a Firestore, przejdź dalej.

Użytkownicy Pythona 2: to opcjonalne ćwiczenia z programowania dotyczące migracji są prezentowane tylko w Pythonie 3, jednak Cloud Firestore obsługuje też wersję 2.x, więc użytkownicy mogą interpolować różnice w użyciu. Jednym z przykładów jest to, że rekordy Firestore używają ciągów Unicode (zamiast ciągów bajtów), więc literały ciągu znaków w Pythonie 2 wymagają wiodącego wskaźnika u'', co oznacza, że funkcja store_visit() 2.x będzie wyglądać tak:

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

Poza tym biblioteka klienta powinna działać podobnie. Jedyną rzeczą, którą trzeba wziąć pod uwagę, jest to, że biblioteka Cloud Firestore 2.x jest „zablokowana”. w rozwoju programowania, więc coraz więcej i nowsze funkcje będą dostępne tylko w bibliotece klienta Firestore w wersji 3.x.

Podczas migracji te podstawowe kroki samouczka:

  1. Konfiguracja/praca
  2. Dodaj bibliotekę Cloud Firestore
  3. Aktualizacja plików aplikacji

3. Konfiguracja/praca

Zanim przejdziemy do głównej części samouczka, skonfigurujmy projekt, pobierz kod, a potem wdróż aplikację bazową. Dzięki temu będziemy wiedzieć, że zaczynamy od działającego kodu.

1. Konfigurowanie projektu

Zalecamy ponowne wykorzystanie tego samego projektu, który został użyty do ukończenia modułu 3 w programie. Możesz też utworzyć nowy projekt lub wykorzystać inny istniejący projekt. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i jest włączone (aplikacja) App Engine.

2. Pobierz przykładową aplikację bazową

Jednym z warunków wstępnych tego ćwiczenia z programowania jest posiadanie działającej przykładowej aplikacji w module 3. Jeśli go nie masz, ukończ samouczek modułu 3 (link powyżej), zanim przejdziesz dalej. Jeśli nie znasz już jej zawartości, możesz zacząć od pobrania poniższego kodu Modułu 3.

Zacznijmy od kodu modułu 3, niezależnie od tego, czy korzystacie z własnego, czy też własnego kodu. W ramach tego ćwiczenia w module 6 z programowania dowiesz się, jak wyglądają poszczególne kroki tego procesu. Po jego zakończeniu proces powinien przypominać kod w punkcie FINISH. (Ten samouczek jest dostępny tylko w przypadku Pythona 3).

Katalog plików modułu 3 (Twoich lub naszych) powinien wyglądać tak:

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

3. Wdróż ponownie aplikację Moduł 3

Pozostałe kroki do wykonania:

  1. Ponownie zapoznaj się z narzędziem wiersza poleceń gcloud (w razie potrzeby)
  2. Wdróż ponownie kod modułu 3 w App Engine (jeśli to konieczne).

Gdy wykonasz te czynności i potwierdzisz, że wszystko działa, przejdziemy do kolejnego samouczka, zaczynając od plików konfiguracji.

Wymagania Pythona 2

  • Sprawdź, czy plik app.yaml (nadal) odwołuje się do pakietów innych firm: grpcio i setuptools.
  • Sprawdź, czy appengine_config.py nadal używa pkg_resources i google.appengine.ext.vendor do wskazywania zasobów zewnętrznych.
  • W następnej sekcji aktualizowanej requirements.txt musisz użyć google-cloud-firestore==1.9.0, ponieważ jest to końcowa wersja biblioteki klienta Firestore zgodnej z 2.x.
    • Jeśli requirements.txt zawiera wpis dotyczący adresu google-cloud-core, pozostaw go bez zmian.
    • Usuń program lib i zainstaluj go ponownie przy użyciu: pip install -t lib -r requirements.txt.

4. Zaktualizuj pliki konfiguracji (dodaj bibliotekę Cloud Firestore)

Oprócz konfiguracji musisz jeszcze zaktualizować konfigurację, a potem pliki aplikacji. W pierwszym przypadku jedyną zmianą konfiguracji jest drobna zamiana pakietów w pliku requirements.txt, więc zróbmy to teraz.

Zastąp wiersz google-cloud-datastore elementem google-cloud-firestore w elemencie requirements.txt, aby wyglądał tak:

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

Zalecamy korzystanie z najnowszych wersji każdej biblioteki. podane wyżej numery wersji są aktualne w momencie tego pisania. Kod w folderze repozytorium FINISH jest aktualizowany częściej i może mieć nowszą wersję.

Nie ma żadnych innych zmian w konfiguracji, więc app.yaml i templates/index.html pozostają bez zmian.

5. Aktualizacja plików aplikacji

Jest tylko 1 plik aplikacji (main.py), więc wszystkie zmiany w tej sekcji dotyczą tylko tego pliku.

1. Importy

Przełączenie importu pakietów jest niewielką zmianą z datastore na firestore:

  • PRZED:
from google.cloud import datastore
  • PO:
from google.cloud import firestore

2. Dostęp do Firestore

Po zainicjowaniu Flask utwórz klienta Firestore. Wprowadź podobną zmianę jak powyżej, ale w przypadku inicjowania klienta:

  • PRZED:
app = Flask(__name__)
ds_client = datastore.Client()
  • PO:
app = Flask(__name__)
fs_client = firestore.Client()

Wykonanie migracji z Cloud NDB do Cloud Datastore pozwoliło Ci już przejść do Cloud Firestore. W Datastore możesz tworzyć rekordy danych w formie encji składających się z wspólnych właściwości i grupować je według kluczy. Rekordy danych w Firestore to dokumenty składające się z par klucz-wartość i pogrupowane w kolekcje. Migracja z Datastore wymaga zastanowienia się nad tymi różnicami, ponieważ pojawiają się one podczas tworzenia rekordów danych oraz wysyłania dotyczących ich zapytań. Wyniki mogą się różnić w zależności od tego, jak złożony jest Twój kod Datastore.

W przypadku Datastore możesz tworzyć zapytania na podstawie typu encji wraz z kryteriami filtrowania i sortowania. W przypadku Firestore podobne są zapytania dotyczące danych. Spójrzmy na krótki przykład, przy założeniu, że następujące wartości zapytań, klienty (odpowiednio ds_client lub fs_client) i importy:

from datetime import datetime
from firestore.Query import DESCENDING

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

W przypadku Datastore wykonajmy zapytanie w kolejności malejącej o 10 najnowszych encji Visit nowszych niż 1 października 2020 r.:

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

Wykonaj te same czynności w przypadku Firestore z kolekcji Visit:

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

Zapytanie do przykładowej aplikacji jest prostsze (brak klauzuli „WHERE”). Oto kod Cloud Datastore:

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

Podczas migracji do Firestore zobaczysz, jak tworzone są nowe dokumenty podobne do encji oraz zapytania w sposób przedstawiony wcześniej.

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

Główna funkcja root() pozostaje taka sama jak plik szablonu index.html. Dokładnie sprawdź zmiany, zapisz je, wdróż i zweryfikuj.

6. Podsumowanie/Czyszczenie

Wdróż aplikację

Wdróż ponownie aplikację za pomocą narzędzia gcloud app deploy i sprawdź, czy działa. Kod powinien być teraz zgodny z tym, co znajduje się w repozytorium modułu 6 (lub w wersji 2.x, jeśli wolisz).

Jeśli dołączysz do tej serii bez wykonania żadnego z poprzednich ćwiczeń z programowania, aplikacja się nie zmieni. rejestruje wszystkie odwiedziny głównej strony internetowej (/) i wygląda tak po tym, jak kilka razy odwiedzisz witrynę:

aplikacja visitme

Gratulujemy ukończenia opcjonalnego modułu 6 migracji. To prawdopodobnie jedna z migracji (o ile nie jest ostateczna), jakie można przeprowadzić w ramach miejsca na dane App Engine. Jeśli jeszcze tego nie zrobiłeś, możesz zastosować konteneryzację aplikacji w Cloud Run (patrz moduły 4 i 5, ćwiczenia z programowania, do których linki znajdują się poniżej).

Opcjonalnie: wyczyść

A co z czyszczeniem, aby uniknąć opłat, dopóki nie wszystko będzie gotowe do przejścia do kolejnego ćwiczenia z programowania dotyczącego migracji? Jako obecni deweloperzy pewnie już znasz informacje o cenach w App Engine.

Opcjonalnie: wyłącz aplikację

Jeśli nie chcesz na razie przejść do następnego samouczka, wyłącz aplikację, aby uniknąć naliczania opłat. Gdy uznasz, że chcesz przejść do kolejnego ćwiczenia w programowaniu, możesz je ponownie włączyć. Gdy Twoja aplikacja jest wyłączona, nie generuje ona opłat za ruch, ale opłaty mogą być jednak naliczane za wykorzystanie Firestorew przypadku przekroczenia bezpłatnego limitu, więc usuń tyle, ile mieści się w tym limicie.

Jeśli natomiast nie zamierzasz kontynuować migracji i chcesz całkowicie usunąć wszystko, możesz wyłączyć projekt.

Dalsze kroki

Oprócz tego samouczka dostępnych jest kilka innych ćwiczeń z programowania modułu migracji, które możesz wziąć pod uwagę:

  • Moduł 7. Kolejki zadań App Engine (wymagane, jeśli korzystasz z kolejek zadań [push])
    • Dodaje zadania push taskqueue w App Engine do aplikacji w module 1
    • Przygotowuje użytkowników do migracji do Cloud Tasks w module 8.
  • Moduł 4: Migracja do Cloud Run z wykorzystaniem Dockera
    • Konteneryzowanie aplikacji w celu uruchamiania jej w Cloud Run za pomocą Dockera
    • Ta migracja pozwoli Ci pozostać w Pythonie 2.
  • Moduł 5. Migracja do Cloud Run za pomocą pakietów Cloud Buildpacks
    • Konteneryzowanie aplikacji na potrzeby uruchamiania jej w Cloud Run za pomocą pakietów Cloud Buildpack
    • Nie musisz wiedzieć nic o Dockerze, kontenerach ani Dockerfile.
    • Wymaga, aby aplikacja została już przeniesiona do Pythona 3 (pakiety Buildpacki nie obsługują Pythona 2).

7. Dodatkowe materiały

Problemy/opinie dotyczące modułu migracji App Engine

Jeśli podczas korzystania z tych ćwiczeń z programowania zauważysz jakiekolwiek problemy, najpierw je wyszukaj. Linki do wyszukiwania i tworzenia nowych problemów:

Zasoby migracji

Linki do folderów repozytorium w modułach 3 (START) i modułach 6 (FINISH) znajdziesz w tabeli poniżej. Dostęp do nich możesz też uzyskać z repozytorium wszystkich migracji App Engine, które możesz sklonować lub pobrać w postaci pliku ZIP.

Codelab

Python 2

Python 3

Część 3

(kod).

kod

Część 6

(nd.)

kod

Zasoby App Engine

Poniżej znajdziesz dodatkowe materiały na temat tej migracji: