Moduł 3. Migracja z Google Cloud NDB do Cloud Datastore

1. Omówienie

Ta seria ćwiczeń z programowania (do samodzielnego ukończenia, praktycznych samouczków) ma pomóc deweloperom w modernizacji aplikacji opartych na Google App Engine (w środowisku standardowym) przez przeprowadzenie serii migracji. Najważniejszym krokiem jest odejście od pierwotnych pakietów usług w ramach środowiska wykonawczego, ponieważ środowiska wykonawcze nowej generacji są bardziej elastyczne, co daje użytkownikom większą różnorodność opcji usług. Przejście na środowisko wykonawcze nowej generacji umożliwia łatwiejsze integrację z usługami Google Cloud, korzystanie z szerszego zakresu obsługiwanych usług i obsługę bieżących wersji językowych.

Ten opcjonalny samouczek pokazuje programistom, jak przejść z Cloud NDB do Cloud Datastore jako biblioteki klienta umożliwiającej komunikację z usługą Datastore. Deweloperzy, którzy wolą używać NDB, mogą z niego korzystać, ponieważ jest on zgodny z językiem Python 3, dlatego ta migracja jest opcjonalna. Ta migracja jest przeznaczona tylko dla tych, którzy chcą utworzyć spójną bazę kodu i biblioteki udostępnione innym aplikacjom, które już korzystają z Cloud Datastore. Zostało to wyjaśnione w „tle”. .

Dowiesz się,

  • Użyj Cloud NDB (jeśli nie znasz tej usługi)
  • Migracja z Cloud NDB do Cloud Datastore
  • Przeprowadź migrację aplikacji do Pythona 3

Czego potrzebujesz

  • projekt Google Cloud Platform z aktywnym kontem rozliczeniowym GCP,
  • Podstawowe umiejętności w języku Python
  • praktyczną znajomość podstawowych poleceń systemu Linux;
  • Podstawowa wiedza na temat tworzenia i wdrażania aplikacji App Engine
  • działającego modułu 2 App Engine 2.x lub 3.x,

Ankieta

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

tylko do przeczytania. Przeczytaj go i wykonaj ćwiczenia
.

2. Tło

Cloud NDB to świetne rozwiązanie Datastore dla wieloletnich programistów App Engine i pomocne w przejściu na Pythona 3, ale nie jedyny sposób, w jaki deweloperzy App Engine mogą uzyskać dostęp do Datastore. Gdy Datastore w 2013 roku w App Engine stał się własną usługą, w Google Cloud Datastore została utworzona nowa biblioteka klienta, dzięki której wszyscy użytkownicy mogą korzystać z Datastore.

Programiści korzystający z Pythona 3 App Engine i spoza App Engine są przekierowywani do używania Cloud Datastore (a nie Cloud NDB). Zachęcamy programistów App Engine korzystających z języka Python 2 do przejścia z ndb do Cloud NDB i portu na Pythona 3, ale mogą także zdecydować się na dalszą migrację do Cloud Datastore. Jest to logiczna decyzja szczególnie dla programistów, którzy mają już kod w Cloud Datastore (np. omówiliśmy już dziś) i chcą tworzyć biblioteki współdzielone we wszystkich swoich aplikacjach. Ponowne używanie kodu to sprawdzona metoda, ponieważ zapewnia spójność kodu. Oba te elementy przyczyniają się do ogólnego zmniejszenia kosztów konserwacji, jak widać poniżej:

Migracja z Cloud NDB do Cloud Datastore

  • Umożliwia programistom skupienie się na pojedynczej bazie kodu dla dostępu do Datastore
  • Unikanie obsługi niektórych kodów przy użyciu Cloud NDB, a innych przy użyciu Cloud Datastore
  • Zapewnia większą spójność w bazie kodu i lepsze ponowne wykorzystanie kodu
  • Umożliwia korzystanie z bibliotek wspólnych lub wspólnych, co przekłada się na niższe ogólne koszty utrzymania.

Ta migracja obejmuje te główne kroki:

  1. Konfiguracja/praca
  2. Zastąp Cloud NDB bibliotekami klienta Cloud Datastore
  3. Aktualizuj aplikację

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

Jeśli masz już za sobą moduł 2 z programowania, zalecamy ponowne wykorzystanie tego samego projektu (i kodu). 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 jest posiadanie działającej przykładowej aplikacji w module 2. Użyj rozwiązania, jeśli udało Ci się ukończyć samouczek. Możesz to zrobić teraz (link powyżej), a jeśli chcesz je pominąć, skopiuj repozytorium modułu 2 (link poniżej).

Zaczniemy od kodu modułu 2 niezależnie od tego, czy korzystasz z jego własnych czy naszych zasobów reklamowych. W ramach tego ćwiczenia w module 3 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 w wersjach Python 2 i 3, więc pobierz odpowiednie repozytorium kodu poniżej.

Python 2

Katalog z plikami START (Twoimi lub naszym) modułu 2 w języku Python 2 powinien wyglądać tak:

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

Jeśli udało Ci się ukończyć samouczek modułu 2, będziesz też mieć folder lib z platformą Flask i jej zależnościami. Jeśli nie masz folderu lib, utwórz go za pomocą polecenia pip install -t lib -r requirements.txt, abyśmy mogli wdrożyć tę podstawową aplikację w następnym kroku. Jeśli masz zainstalowany język Python 2 i 3, zalecamy użycie pip2 zamiast pip, aby uniknąć nieporozumień z Pythonem 3.

Python 3

Katalog z plikami START (Twoimi lub naszym) modułu 2 w języku Python 3 powinien wyglądać tak:

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

W języku Python 3 nie jest używany ani lib, ani appengine_config.py.

3. Wdróż ponownie aplikację Moduł 2

Pozostałe kroki do wykonania:

  1. Ponownie zapoznaj się z narzędziem wiersza poleceń gcloud (w razie potrzeby)
  2. (Ponowne) wdrożenie kodu modułu 1 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.

4. Zastąp Cloud NDB bibliotekami klienta Cloud Datastore

Jedyną zmianą w konfiguracji jest drobna zamiana pakietów w pliku requirements.txt.

1. Zaktualizuj: requirements.txt

Po ukończeniu modułu 2 Twój plik requirements.txt wyglądał tak:

  • PRZED (Python 2 i 3):
Flask==1.1.2
google-cloud-ndb==1.7.1

Zaktualizuj requirements.txt, zastępując bibliotekę Cloud NDB (google-cloud-ndb) najnowszą wersją biblioteki Cloud Datastore (google-cloud-datastore). Pozostaw wpis dla Flask bez zmian. Pamiętaj, że ostateczna wersja Cloud Datastore zgodna z Pythonem 2 to wersja 1.15.3:

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

Pamiętaj, że repozytorium jest obsługiwane bardziej regularnie niż ten samouczek, więc może się zdarzyć, że plik requirements.txt będzie odzwierciedlać nowsze wersje. Zalecamy używanie najnowszych wersji każdej biblioteki, ale jeśli to nie pomoże, możesz przywrócić starszą wersję. Powyższe numery wersji pochodzą z najnowszej daty ostatniej aktualizacji tego ćwiczenia z programowania.

2. Inne pliki konfiguracji

Pozostałe pliki konfiguracji (app.yaml i appengine_config.py) powinny pozostać niezmienione w porównaniu z poprzednim krokiem migracji:

  • Pole app.yaml powinno (nadal) odwoływać się do pakietów innych firm (grpcio i setuptools).
  • appengine_config.py powinien (nadal) wskazywać pkg_resources i google.appengine.ext.vendor zewnętrzne zasoby w lib.

Teraz przejdźmy do plików aplikacji.

5. Aktualizacja plików aplikacji

template/index.html nie ma żadnych zmian, ale mamy kilka aktualizacji dotyczących urządzenia main.py.

1. Importy

Kod początkowy sekcji importowania powinien wyglądać tak:

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

Zastąp import google.cloud.ndb jednym z nich dla Cloud Datastore: google.cloud.datastore. Biblioteka klienta Datastore nie obsługuje automatycznego tworzenia pola sygnatury czasowej w elemencie, dlatego zaimportuj też standardowy moduł datetime biblioteki, aby utworzyć go ręcznie. Zgodnie z konwencją importy z bibliotek standardowych są większe niż importy pakietów firm zewnętrznych. Po wprowadzeniu zmian powinno to wyglądać mniej więcej tak:

  • PO:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore

2. Inicjalizacja i model danych

Po zainicjowaniu Flask przykładowa aplikacja z modułu 2 tworzy klasę modelu danych NDB i jej pola w ten sposób:

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

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

Biblioteka Cloud Datastore nie ma takiej klasy, więc usuń deklarację klasy Visit. Aby komunikować się z Datastore, potrzebujesz klienta, więc zmień ndb.Client() na datastore.Client(). Biblioteka Datastore jest bardziej „elastyczna”, umożliwiając tworzenie elementów bez wcześniejszego zgłaszania taką jak NDB. Po tej aktualizacji ta część main.py powinna wyglądać tak:

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

3. Dostęp do Datastore

Migracja do Cloud Datastore wymaga zmiany sposobu tworzenia i przechowywania elementów Datastore oraz wysyłania do nich zapytań (na poziomie użytkownika). Trudność migracji w przypadku Twoich aplikacji zależy od tego, jak złożony jest kod Datastore. W naszej przykładowej aplikacji postaraliśmy się maksymalnie uprościć aktualizację. Oto nasz kod początkowy:

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

W Cloud Datastore utwórz encję ogólną, identyfikującą zgrupowane obiekty w elemencie za pomocą „klucza”. Utwórz rekord danych z obiektem JSON (Python dict) zawierającym pary klucz-wartość, a następnie zapisz go w Datastore z oczekiwaną wartością put(). Zapytania są podobne, ale prostsze w Datastore. Tutaj możesz zobaczyć, czym różni się odpowiedni kod Datastore:

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

Zaktualizuj treść funkcji store_visit() i fetch_visits() w sposób opisany powyżej, zachowując ich podpisy identyczne jak w poprzedniej wersji. Główny moduł obsługi root() nie ulega zmianie. Po wprowadzeniu tych zmian Twoja aplikacja jest gotowa do użycia w Cloud Datastore i jest gotowa do testów.

6. Podsumowanie/Czyszczenie

Wdróż aplikację

Wdróż ponownie aplikację za pomocą narzędzia gcloud app deploy i sprawdź, czy działa. Twój kod powinien teraz odpowiadać zawartości folderów repozytorium w module 3:

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 modułu 3 ćwiczenia z programowania. Wiesz już, że aby uzyskać dostęp do Datastore, możesz używać zarówno bibliotek klienta Cloud NDB jak i Cloud Datastore. Przejście na drugą wersję pozwoliło uzyskać korzyści takie jak biblioteki współdzielone oraz powszechny kod i możliwość ponownego wykorzystania kodu, co pozwoli zapewnić spójność i obniżyć koszty utrzymania.

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 magazynu danychw przypadku przekroczenia bezpłatnego limitu, więc usuń tyle miejsca, aby nie przekroczyć tego limitu.

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

Dalsze kroki

Tutaj możesz zapoznać się z kolejnymi modułami migracji:

  • Bonus 3 – Bonus: Przejdź do sekcji poświęconej bonusom, aby dowiedzieć się, jak przenieść kod do Pythona 3 i środowiska wykonawczego App Engine nowej generacji.
  • 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
    • Pozwala na pozostanie 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 muszą niczego wiedzieć o Dockerze, kontenerach ani Dockerfile.
    • Wymaga wcześniejszej migracji aplikacji do Pythona 3
  • Moduł 6. Migracja do Cloud Firestore
    • Przejdź na Cloud Firestore, aby uzyskać dostęp do funkcji Firebase
    • Cloud Firestore obsługuje język Python 2, ale to ćwiczenia z programowania są dostępne tylko w Pythonie 3.

7. BONUS: przejdź na Pythona 3

Aby uzyskać dostęp do najnowszego środowiska wykonawczego i funkcji App Engine, zalecamy przejście na Pythona 3. W naszej przykładowej aplikacji Datastore był jedyną usługą wbudowaną, której użyliśmy, a ponieważ przeszliśmy z ndb na Cloud NDB, możemy teraz przenieść port do środowiska wykonawczego Pythona 3 App Engine.

Omówienie

Chociaż portowanie do Pythona 3 nie jest częścią samouczka Google Cloud, ta część ćwiczenia w Codelabs pozwala programistom poznać różnice między środowiskiem wykonawczym App Engine w języku Python 3. Wyjątkową cechą środowiska wykonawczego nowej generacji jest uproszczony dostęp do pakietów innych firm: nie trzeba określać wbudowanych pakietów w app.yaml ani kopiować lub przesyłać niewbudowanych bibliotek. są domyślnie instalowane z poziomu listy requirements.txt.

Nasz przykład jest tak podstawowy a Cloud Datastore jest zgodny z językiem Python 2–3, więc żaden kod aplikacji nie musi być jawnie przeniesiony do wersji 3.x. Aplikacja działa na platformach 2.x i 3.x bez modyfikacji, co oznacza, że w tym przypadku wymagane zmiany są tylko w konfiguracji:

  1. Uprość kod app.yaml, aby odwoływać się do Pythona 3 i usunąć odniesienia do pakietów z bibliotekami innych firm.
  2. Usuń appengine_config.py i folder lib, ponieważ nie są już potrzebne.

Pliki aplikacji main.py i templates/index.html pozostają niezmienione.

Zaktualizuj: requirements.txt

Ostateczna wersja Cloud Datastore obsługująca Pythona 2 to 1.15.3. Zaktualizuj requirements.txt do najnowszej wersji Pythona 3 (może być już nowsza). Po pisaniu tego samouczka najnowsza wersja to 2.1.0, dlatego zmień ten wiersz tak, aby wyglądał (lub w innej najnowszej wersji):

google-cloud-datastore==2.1.0

Uprość: app.yaml

PRZED:

Jedyną rzeczywistą zmianą w tej przykładowej aplikacji jest znaczne skrócenie wartości app.yaml. Dla przypomnienia: oto, co wspomnieliśmy w app.yamlmodule 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

PO:

W Pythonie 3 dyrektywy threadsafe, api_version i libraries zostały wycofane. Wszystkie aplikacje są uznawane za bezpieczne wątkowo, a zasada api_version nie jest używana w Pythonie 3. W usługach App Engine nie ma już wbudowanych pakietów innych firm, dlatego pakiet libraries również został wycofany. Więcej informacji o tych zmianach znajdziesz w dokumentacji zmian w app.yaml. W związku z tym usuń wszystkie 3 elementy z app.yaml i zaktualizuj je do obsługiwanej wersji Pythona 3 (patrz poniżej).

Opcjonalnie: użycie dyrektywy handlers

Poza tym dyrektywa handlers, która kieruje ruch do aplikacji App Engine, również została wycofana. Środowisko wykonawcze nowej generacji oczekuje, że platformy internetowe będą zarządzać routingiem aplikacji, dlatego wszystkie „skrypty obsługi” należy zmienić na „auto”. Po połączeniu powyższych zmian otrzymasz następującą liczbę elementów app.yaml:

runtime: python38

handlers:
- url: /.*
  script: auto

Dowiedz się więcej o script: auto ze strony referencyjnej app.yaml.

Usuwam dyrektywę handlers

Ponieważ interfejs handlers został wycofany, możesz też usunąć całą sekcję, pozostawiając jednowierszowy app.yaml:

runtime: python38

Domyślnie uruchamiany jest serwer WWW Gunicorn WSGI, który jest dostępny dla wszystkich aplikacji. Jeśli znasz język gunicorn, oto polecenie wykonywane, gdy jest uruchamiane domyślnie z bonusem app.yaml:

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

Opcjonalnie: użycie dyrektywy entrypoint

Jeśli jednak Twoja aplikacja wymaga konkretnego polecenia uruchamiania, można je podać za pomocą dyrektywy entrypoint. W takim przypadku app.yaml będzie wyglądać tak:

runtime: python38
entrypoint: python main.py

W tym przykładzie konkretnie zażądano użycia serwera programistycznego Flask zamiast gunicorn. Kod uruchamiający serwer programistyczny należy również dodać do aplikacji w interfejsie 0.0.0.0 na porcie 8080. W tym celu dodaj tę małą sekcję na dole kodu main.py:

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

Dowiedz się więcej o entrypoint ze strony referencyjnej app.yaml. Więcej przykładów i sprawdzonych metod znajdziesz w dokumentach dotyczących uruchamiania standardowego środowiska w App Engine oraz w dokumentach dotyczących uruchamiania elastycznego środowiska App Engine.

Usuń appengine_config.py i lib

Usuń plik appengine_config.py i folder lib. Podczas migracji do Pythona 3 App Engine pozyskuje i instaluje pakiety wymienione w regionie requirements.txt.

Plik konfiguracyjny appengine_config.py służy do rozpoznawania bibliotek/pakietów innych firm, niezależnie od tego, czy zostały one skopiowane przez Ciebie, czy też używasz już istniejących na serwerach App Engine (wbudowanych). Podsumowanie najważniejszych zmian po przejściu do Pythona 3:

  1. Nie pakuję skopiowanych bibliotek innych firm (wymienionych w regionie requirements.txt)
  2. Brak elementów pip install do folderu lib, co oznacza brak okresu folderu lib
  3. Brak informacji o wbudowanych bibliotekach innych firm w app.yaml
  4. Nie trzeba odwoływać się do bibliotek innych firm, więc nie ma pliku appengine_config.py

Wystarczy, że umieścisz w pliku requirements.txt listę wszystkich wymaganych bibliotek innych firm.

Wdróż aplikację

Wdróż aplikację ponownie, aby sprawdzić, czy działa. Możesz też sprawdzić, jak blisko Twojego rozwiązania jest przykładowy kod w module 3 w Pythonie 3. Aby zwizualizować różnice w stosunku do języka Python 2, porównaj ten kod z jego wersją w języku Python 2.

Gratulacje! Udało Ci się ukończyć bonusowy krok w module 3. Zapoznaj się z dokumentacją dotyczącą przygotowywania plików konfiguracji na potrzeby środowiska wykonawczego Pythona 3. Przejrzyj wcześniejsze podsumowanie powyżej, aby dowiedzieć się, co zrobić dalej i jak wyczyścić dane.

Przygotowywanie Twojej aplikacji

Przy migrowaniu swojej aplikacji trzeba będzie przenieść main.py i inne pliki aplikacji do wersji 3.x, więc najlepiej jest postarać się, aby aplikacja 2.x była „zgodna do przekazywania dalej”. jak to tylko możliwe.

W internecie znajdziesz wiele materiałów, które Ci w tym pomogą. Oto kilka najważniejszych wskazówek:

  1. Sprawdź, czy wszystkie zależności aplikacji są w pełni zgodne z wersją 3.x
  2. Upewnij się, że aplikacja działa w wersji 2.6 (najlepiej 2.7).
  3. Sprawdź, czy aplikacja przeszła cały pakiet testów (i co najmniej 80% pokrycia)
  4. Używaj bibliotek zgodności, takich jak six, Future lub Modernize
  5. Zdobądź wiedzę na temat niekompatybilności wstecznej kluczy w wersjach 2.x i 3.x
  6. Każde wejście/wyjście prawdopodobnie prowadzi do niezgodności z Unicode i ciągami bajtów.

Właśnie dlatego została opracowana przykładowa aplikacja, dlatego działa na 2.x i 3.x.

8. 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 2 (START) i modułach 3 (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ęść 2

kod

kod

Część 3

kod

kod

Zasoby App Engine

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