1. Przegląd
Seria ćwiczeń z programowania Serverless Migration Station (samodzielne, praktyczne samouczki) i powiązane filmy mają na celu pomóc deweloperom bezserwerowych rozwiązań Google Cloud w modernizacji aplikacji przez przeprowadzenie ich przez co najmniej 1 migrację, głównie odchodząc od starszych usług. Dzięki temu aplikacje są bardziej przenośne, a Ty masz więcej opcji i większą elastyczność, co umożliwia integrację z szerszą gamą usług Cloud i dostęp do nich, a także łatwiejsze uaktualnianie do nowszych wersji językowych. Chociaż początkowo skupiamy się na najwcześniejszych użytkownikach Cloud, głównie deweloperach App Engine (środowisko standardowe), ta seria jest na tyle szeroka, że obejmuje inne platformy bezserwerowe, takie jak Cloud Functions i Cloud Run, lub inne, jeśli ma to zastosowanie.
To ćwiczenie z modułu 15 wyjaśnia, jak dodać korzystanie z App Engine blobstore do przykładowej aplikacji z modułu 0. Następnie w module 16 dowiesz się, jak przenieść to wykorzystanie do Cloud Storage.
Dowiesz się, jak:
- Dodanie interfejsu API lub biblioteki Blobstore w App Engine
- Przechowuj pliki przesyłane przez użytkowników w usłudze
blobstore - Przygotowanie do kolejnego kroku migracji do Cloud Storage
Czego potrzebujesz
- projekt Google Cloud Platform z aktywnym kontem rozliczeniowym GCP,
- podstawowe umiejętności programowania w Pythonie,
- Praktyczna znajomość typowych poleceń systemu Linux.
- podstawowa wiedza na temat tworzenia i wdrażania aplikacji App Engine;
- działająca aplikacja App Engine z modułu 0 (pobierz z repozytorium).
Ankieta
Jak będziesz korzystać z tego samouczka?
Jak oceniasz swoje doświadczenie z Pythonem?
Jak oceniasz swoje wrażenia z korzystania z usług Google Cloud?
2. Tło
Aby przeprowadzić migrację z interfejsu Blobstore API w App Engine, dodaj jego użycie do istniejącej podstawowej aplikacji App Engine ndb z modułu 0. Przykładowa aplikacja wyświetla 10 ostatnich wizyt użytkownika. Modyfikujemy aplikację, aby prosiła użytkownika o przesłanie artefaktu (pliku) odpowiadającego jego „wizycie”. Jeśli użytkownik nie chce tego zrobić, może wybrać opcję „Pomiń”. Niezależnie od decyzji użytkownika na następnej stronie wyświetlane są te same dane wyjściowe co w aplikacji z modułu 0 (i wielu innych modułów z tej serii). Po wdrożeniu integracji App Engine z blobstore możemy przeprowadzić migrację do Cloud Storage w następnym ćwiczeniu (moduł 16).
App Engine zapewnia dostęp do systemów szablonów Django i Jinja2. Jedną z rzeczy, które odróżniają ten przykład (oprócz dodania dostępu do Blobstore), jest to, że w module 15 przechodzi on z Django w module 0 na Jinja2. Kluczowym krokiem w modernizacji aplikacji App Engine jest migracja platform internetowych z webapp2 do Flask. Ten ostatni używa Jinja2 jako domyślnego systemu szablonów, więc zaczynamy zmierzać w tym kierunku, wdrażając Jinja2, ale pozostając przy webapp2 w celu uzyskania dostępu do Blobstore. Flask domyślnie używa Jinja2, więc w module 16 nie trzeba będzie wprowadzać żadnych zmian w szablonie.
3. Konfiguracja/przygotowanie
Zanim przejdziemy do głównej części samouczka, skonfiguruj projekt, pobierz kod i wdróż aplikację bazową, aby zacząć od działającego kodu.
1. Konfigurowanie projektu
Jeśli aplikacja z modułu 0 została już wdrożona, zalecamy ponowne użycie tego samego projektu (i kodu). Możesz też utworzyć zupełnie nowy projekt lub użyć innego istniejącego projektu. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i czy usługa App Engine jest włączona.
2. Pobieranie przykładowej aplikacji bazowej
Jednym z wymagań wstępnych tego ćwiczenia jest działająca przykładowa aplikacja z modułu 0. Jeśli jej nie masz, możesz ją pobrać z folderu „START” modułu 0 (link poniżej). W tym ćwiczeniu przeprowadzimy Cię przez każdy krok, a na koniec otrzymasz kod podobny do tego, który znajduje się w folderze „FINISH” modułu 15.
- START: folder Module 0 (Python 2)
- FINISH: folder modułu 15 (Python 2)
- Całe repozytorium (do sklonowania lub pobrania pliku ZIP)
Katalog plików START modułu 0 powinien wyglądać tak:
$ ls README.md index.html app.yaml main.py
3. (Ponowne) wdrażanie aplikacji bazowej
Pozostałe czynności przygotowawcze, które należy wykonać:
- Przypomnij sobie, jak działa narzędzie wiersza poleceń
gcloud. - Ponowne wdrażanie przykładowej aplikacji za pomocą
gcloud app deploy - Sprawdzanie, czy aplikacja działa w App Engine bez problemów
Gdy wykonasz te czynności i zobaczysz, że aplikacja internetowa działa (z danymi wyjściowymi podobnymi do poniższych), możesz dodać do niej pamięć podręczną.

4. Aktualizowanie plików konfiguracji
app.yaml
Nie ma żadnych istotnych zmian w konfiguracji aplikacji, ale jak wspomnieliśmy wcześniej, przechodzimy z szablonów Django (domyślnych) na Jinja2. Aby dokonać zmiany, użytkownicy powinni określić najnowszą wersję Jinja2 dostępną na serwerach App Engine, dodając ją do sekcji wbudowanych bibliotek innych firm w pliku app.yaml.
PRZED:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Zmodyfikuj plik app.yaml, dodając nową sekcję libraries, jak pokazano poniżej:
AFTER:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
Nie trzeba aktualizować żadnych innych plików konfiguracji, więc przejdźmy do plików aplikacji.
5. Modyfikowanie plików aplikacji
Obsługa importu i Jinja2
Pierwszy zestaw zmian w aplikacji main.py obejmuje dodanie interfejsu Blobstore API i zastąpienie szablonów Django szablonami Jinja2. Co się zmienia:
- Moduł
ossłuży do tworzenia ścieżki do pliku szablonu Django. Przechodzimy na Jinja2, gdzie jest to obsługiwane, więc użycieosoraz mechanizmu renderowania szablonów Django,google.appengine.ext.webapp.template, nie jest już potrzebne, dlatego zostaną one usunięte. - Zaimportuj interfejs Blobstore API:
google.appengine.ext.blobstore - Zaimportuj moduły obsługi Blobstore znalezione w pierwotnej platformie
webapp– nie są one dostępne wwebapp2:google.appengine.ext.webapp.blobstore_handlers - Zaimportuj obsługę Jinja2 z pakietu
webapp2_extras.
PRZED:
import os
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template
Wprowadź zmiany z listy powyżej, zastępując bieżącą sekcję importu w pliku main.py poniższym fragmentem kodu.
AFTER:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Po importach dodaj powtarzalny kod, który umożliwi korzystanie z Jinja2 zgodnie z opisem w dokumentacji webapp2_extras. Poniższy fragment kodu opakowuje standardową klasę modułu obsługi żądań webapp2 funkcjami Jinja2, więc dodaj ten blok kodu do pliku main.py zaraz po importach:
class BaseHandler(webapp2.RequestHandler):
'Derived request handler mixing-in Jinja2 support'
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
self.response.write(self.jinja2.render_template(_template, **context))
Dodawanie obsługi Blobstore
W przeciwieństwie do innych migracji z tej serii, w których zachowujemy funkcjonalność lub dane wyjściowe przykładowej aplikacji (lub prawie takie same) bez (większych) zmian w UX, ten przykład jest bardziej radykalnym odejściem od normy. Zamiast natychmiast rejestrować nową wizytę, a następnie wyświetlać 10 ostatnich, aktualizujemy aplikację, aby prosiła użytkownika o plik, za pomocą którego zarejestruje wizytę. Użytkownicy mogą przesłać odpowiedni plik lub wybrać „Pomiń”, aby nic nie przesyłać. Po wykonaniu tego kroku wyświetli się strona „Ostatnie wizyty”.
Dzięki tej zmianie nasza aplikacja może używać usługi Blobstore do przechowywania (i ewentualnie późniejszego renderowania) tego obrazu lub innego typu pliku na stronie ostatnich wizyt.
Zaktualizuj model danych i wdroż jego użycie
Przechowujemy więcej danych, a konkretnie aktualizujemy model danych, aby przechowywać identyfikator (nazywany „BlobKey”) pliku przesłanego do Blobstore i dodajemy odwołanie, aby zapisać go w store_visit(). Te dodatkowe dane są zwracane wraz z innymi danymi w odpowiedzi na zapytanie, więc fetch_visits() pozostaje bez zmian.
Oto porównanie przed i po wprowadzeniu tych zmian na przykładzie file_blob, ndb.BlobKeyProperty:
PRZED:
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'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
AFTER:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.BlobKeyProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
Oto graficzne przedstawienie zmian, które zostały wprowadzone do tej pory:

Obsługa przesyłania plików
Najważniejszą zmianą w funkcjonalności jest obsługa przesyłania plików, niezależnie od tego, czy chodzi o proszenie użytkownika o plik, obsługę funkcji „pomiń” czy renderowanie pliku odpowiadającego wizycie. Wszystko to jest częścią obrazu. Aby umożliwić przesyłanie plików, musisz wprowadzić te zmiany:
- Żądanie głównego modułu obsługi
GETnie pobiera już najnowszych wizyt do wyświetlenia. Zamiast tego prosi użytkownika o przesłanie pliku. - Gdy użytkownik przesyła plik lub pomija ten proces,
POSTz formularza przekazuje kontrolę do nowegoUploadHandler, pochodzącego zgoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler. - Metoda
POSTklasyUploadHandlerprzesyła plik, wywołuje metodęstore_visit(), aby zarejestrować wizytę, i wyzwala przekierowanie HTTP 307, aby odesłać użytkownika z powrotem do „/”, gdzie… - Metoda
POSTgłównego modułu obsługi wysyła zapytanie (za pomocąfetch_visits()) i wyświetla ostatnie wizyty. Jeśli użytkownik wybierze „Pomiń”, plik nie zostanie przesłany, ale wizyta zostanie zarejestrowana, a następnie nastąpi przekierowanie. - Wyświetlane ostatnie wizyty zawierają nowe pole, które jest widoczne dla użytkownika. Jest to hiperlink „Wyświetl”, jeśli plik do przesłania jest dostępny, lub „Brak”, jeśli nie jest dostępny. Te zmiany zostaną wprowadzone w szablonie HTML wraz z dodaniem formularza przesyłania (więcej informacji na ten temat: Już wkrótce).
- Jeśli użytkownik kliknie link „Wyświetl” w przypadku wizyty z przesłanym filmem, wysyła żądanie
GETdo nowegoViewBlobHandler, pochodzącego zgoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler, które renderuje plik, jeśli jest to obraz (w przeglądarce, jeśli jest obsługiwany), wyświetla prośbę o pobranie, jeśli nie, lub zwraca błąd HTTP 404, jeśli nie zostanie znaleziony. - Oprócz nowej pary klas modułów obsługi i nowej pary tras do wysyłania do nich ruchu główny moduł obsługi potrzebuje nowej metody
POST, aby otrzymywać opisane powyżej przekierowanie 307.
Przed wprowadzeniem tych zmian aplikacja z modułu 0 zawierała tylko główny moduł obsługi z metodą GET i jedną trasą:
PRZED:
class MainHandler(webapp2.RequestHandler):
'main application (GET) handler'
def get(self):
store_visit(self.request.remote_addr, self.request.user_agent)
visits = fetch_visits(10)
tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(tmpl, {'visits': visits}))
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
Po wprowadzeniu tych zmian mamy teraz 3 moduły obsługi: 1) moduł obsługi przesyłania z metodą POST, 2) moduł obsługi pobierania „view blob” z metodą GET oraz 3) główny moduł obsługi z metodami GET i POST. Wprowadź te zmiany, aby reszta aplikacji wyglądała tak jak poniżej.
AFTER:
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
'Upload blob (POST) handler'
def post(self):
uploads = self.get_uploads()
blob_id = uploads[0].key() if uploads else None
store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
self.redirect('/', code=307)
class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
'view uploaded blob (GET) handler'
def get(self, blob_key):
self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)
class MainHandler(BaseHandler):
'main application (GET/POST) handler'
def get(self):
self.render_response('index.html',
upload_url=blobstore.create_upload_url('/upload'))
def post(self):
visits = fetch_visits(10)
self.render_response('index.html', visits=visits)
app = webapp2.WSGIApplication([
('/', MainHandler),
('/upload', UploadHandler),
('/view/([^/]+)?', ViewBlobHandler),
], debug=True)
W dodanym kodzie znajduje się kilka kluczowych wywołań:
- W funkcji
MainHandler.getznajduje się wywołanie funkcjiblobstore.create_upload_url. To wywołanie generuje adres URL, do którego formularz wysyła żądaniePOST, wywołując moduł obsługi przesyłania, aby wysłać plik do Blobstore. - W funkcji
UploadHandler.postznajduje się wywołanie funkcjiblobstore_handlers.BlobstoreUploadHandler.get_uploads. To jest prawdziwa magia, która umieszcza plik w Blobstore i zwraca unikalny i trwały identyfikator tego pliku, czyliBlobKey. - W
ViewBlobHandler.getwywołanieblobstore_handlers.BlobstoreDownloadHandler.sendzBlobKeypliku powoduje pobranie pliku i przekazanie go do przeglądarki użytkownika
Te wywołania stanowią większość dostępu do funkcji dodanych do aplikacji. Oto graficzne przedstawienie drugiego i ostatniego zestawu zmian w aplikacji main.py:

Aktualizowanie szablonu HTML
Niektóre aktualizacje głównej aplikacji wpływają na jej interfejs, dlatego w szablonie internetowym trzeba wprowadzić odpowiednie zmiany. Są to 2 modyfikacje:
- Wymagany jest formularz przesyłania pliku z 3 elementami wejściowymi: plikiem i parą przycisków przesyłania, odpowiednio do przesyłania pliku i pomijania.
- Zaktualizuj dane wyjściowe dotyczące ostatnich wizyt, dodając link „Wyświetl” w przypadku wizyt z odpowiednim przesłanym plikiem lub „Brak” w przeciwnym razie.
PRZED:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
</body>
</html>
Wprowadź zmiany z listy powyżej, aby utworzyć zaktualizowany szablon:
AFTER:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
{% if upload_url %}
<h3>Welcome... upload a file? (optional)</h3>
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><p></p>
<input type="submit"> <input type="submit" value="Skip">
</form>
{% else %}
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }}
<i><code>
{% if visit.file_blob %}
(<a href="/view/{{ visit.file_blob }}" target="_blank">view</a>)
{% else %}
(none)
{% endif %}
</code></i>
from {{ visit.visitor }}
</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>
Ten obraz przedstawia wymagane aktualizacje index.html:

Ostatnia zmiana polega na tym, że Jinja2 preferuje szablony w folderze templates, więc utwórz ten folder i przenieś do niego plik index.html. To ostatnia zmiana, którą musisz wprowadzić, aby dodać Blobstore do przykładowej aplikacji z modułu 0.
(opcjonalnie) „Ulepszenie” Cloud Storage
Z czasem Blobstore przekształcił się w Cloud Storage. Oznacza to, że przesłane pliki Blobstore są widoczne w konsoli Cloud, a konkretnie w przeglądarce Cloud Storage. Pytanie brzmi: gdzie? Odpowiedź brzmi: domyślny zasobnik Cloud Storage aplikacji App Engine. Jego nazwa to pełna nazwa domeny aplikacji App Engine, PROJECT_ID.appspot.com. To bardzo wygodne, ponieważ wszystkie identyfikatory projektów są unikalne.
Aktualizacje wprowadzone w przykładowej aplikacji powodują, że przesłane pliki trafiają do tego zasobnika, ale deweloperzy mogą wybrać bardziej konkretną lokalizację. Domyślny zasobnik jest dostępny programowo przez google.appengine.api.app_identity.get_default_gcs_bucket_name(), co wymaga nowego importu, jeśli chcesz uzyskać dostęp do tej wartości, np. aby użyć jej jako prefiksu do porządkowania przesłanych plików. Na przykład sortowanie według typu pliku:

Aby zaimplementować coś takiego na przykład w przypadku obrazów, użyj kodu podobnego do tego, który sprawdza typy plików, aby wybrać żądaną nazwę zasobnika:
ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')
Przesłane obrazy sprawdzisz też za pomocą narzędzia takiego jak moduł imghdr biblioteki standardowej Pythona, aby potwierdzić typ obrazu. Na koniec warto ograniczyć rozmiar przesyłanych plików na wypadek, gdyby ktoś chciał przesłać coś niepożądanego.
Załóżmy, że wszystkie te czynności zostały wykonane. Jak możemy zaktualizować naszą aplikację, aby obsługiwała określanie miejsca przechowywania przesłanych plików? Kluczem jest zmodyfikowanie wywołania blobstore.create_upload_url w MainHandler.get, aby określić żądaną lokalizację w Cloud Storage na potrzeby przesyłania, przez dodanie parametru gs_bucket_name w ten sposób:
blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))
Jest to opcjonalna aktualizacja, jeśli chcesz określić, gdzie mają być przesyłane pliki, więc nie jest ona częścią pliku main.py w repozytorium. Zamiast tego w repozytorium dostępna jest alternatywa o nazwie main-gcs.py. Zamiast używać osobnego „folderu” zasobnika, kod w main-gcs.py przechowuje przesłane pliki w zasobniku „głównym” (PROJECT_ID.appspot.com) tak jak main.py, ale zapewnia rusztowanie, którego potrzebujesz, jeśli chcesz przekształcić próbkę w coś więcej, jak sugerowano w tej sekcji. Poniżej znajdziesz ilustrację przedstawiającą różnice między main.py a main-gcs.py.

6. Podsumowanie i czyszczenie
W tej sekcji podsumujemy ćwiczenia z programowania, wdrażając aplikację i sprawdzając, czy działa zgodnie z oczekiwaniami i czy dane wyjściowe są prawidłowe. Po sprawdzeniu aplikacji wykonaj czynności związane z czyszczeniem i zastanów się nad kolejnymi krokami.
Wdrażanie i weryfikowanie aplikacji
Ponownie wdróż aplikację za pomocą gcloud app deploy i sprawdź, czy działa zgodnie z opisem, różniąc się od aplikacji z modułu 0 pod względem wrażeń użytkownika. Aplikacja ma teraz 2 różne ekrany. Pierwszy to prośba o przesłanie pliku:
Użytkownicy mogą przesłać plik i kliknąć „Prześlij” lub kliknąć „Pomiń”, aby nic nie przesyłać. W obu przypadkach wyświetli się ekran ostatniej wizyty, który teraz zawiera linki „Wyświetl” lub „Brak” między sygnaturami czasowymi wizyty a informacjami o użytkowniku:

Gratulujemy ukończenia tego ćwiczenia z programowania, w którym dodaliśmy Blobstore w App Engine do przykładowej aplikacji z modułu 0. Twój kod powinien teraz odpowiadać zawartości folderu FINISH (moduł 15). W tym folderze znajduje się też alternatywny plik main-gcs.py.
Czyszczenie danych
Ogólne
Jeśli na razie nie chcesz kontynuować, zalecamy wyłączenie aplikacji App Engine, aby uniknąć naliczania opłat. Jeśli jednak chcesz przeprowadzić więcej testów lub eksperymentów, platforma App Engine ma bezpłatny limit, więc dopóki nie przekroczysz tego poziomu wykorzystania, nie powinny być naliczane opłaty. To są koszty obliczeń, ale mogą też zostać naliczone opłaty za odpowiednie usługi App Engine, więc więcej informacji znajdziesz na stronie z cennikiem. Jeśli migracja obejmuje inne usługi Cloud, są one rozliczane osobno. W obu przypadkach zapoznaj się z sekcją „Informacje dotyczące tego ćwiczenia” poniżej.
Warto wiedzieć, że wdrożenie na bezserwerowej platformie obliczeniowej Google Cloud, takiej jak App Engine, wiąże się z niewielkimi kosztami kompilacji i przechowywania danych. Cloud Build ma własny bezpłatny limit, podobnie jak Cloud Storage. Przechowywanie tego obrazu wykorzystuje część tego limitu. Możesz jednak mieszkać w regionie, w którym nie ma takiego poziomu bezpłatnego, więc zwracaj uwagę na wykorzystanie miejsca na dane, aby zminimalizować potencjalne koszty. Konkretne „foldery” Cloud Storage, które należy sprawdzić, to:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Linki do miejsca przechowywania powyżej zależą od
PROJECT_IDi *LOC*ation, na przykład „us”, jeśli aplikacja jest hostowana w USA.
Jeśli jednak nie zamierzasz kontynuować pracy z tą aplikacją ani innymi powiązanymi z nią programami do migracji i chcesz usunąć wszystko, zamknij projekt.
Dotyczy tego ćwiczenia
Usługi wymienione poniżej są unikalne dla tego ćwiczenia z programowania. Więcej informacji znajdziesz w dokumentacji poszczególnych usług:
- Usługa Blobstore App Engine podlega limitom przechowywanych danych, dlatego zapoznaj się z nimi, a także ze stroną z cenami starszych usług powiązanych.
- Usługa App Engine Datastore jest świadczona przez Cloud Datastore (Cloud Firestore w trybie Datastore), która również ma poziom bezpłatny. Więcej informacji znajdziesz na stronie z cennikiem.
Dalsze kroki
Kolejna logiczna migracja, którą warto rozważyć, jest opisana w module 16. Pokazuje ona deweloperom, jak przejść z usługi Blobstore w App Engine na bibliotekę klienta Cloud Storage. Korzyści z uaktualnienia obejmują dostęp do większej liczby funkcji Cloud Storage, zapoznanie się z biblioteką klienta, która działa w aplikacjach poza App Engine, zarówno w Google Cloud, innych chmurach, jak i lokalnie. Jeśli nie potrzebujesz wszystkich funkcji dostępnych w Cloud Storage lub obawiasz się, że wpłynie to na koszty, możesz pozostać przy blobstore w App Engine.
Po module 16 dostępnych jest wiele innych możliwych migracji, takich jak Cloud NDB i Cloud Datastore, Cloud Tasks czy Cloud Memorystore. Dostępne są też migracje między usługami do Cloud Run i Cloud Functions. Repozytorium migracji zawiera wszystkie przykładowe kody, linki do wszystkich dostępnych ćwiczeń programistycznych i filmów, a także wskazówki dotyczące migracji, które warto rozważyć, oraz odpowiednią „kolejność” migracji.
7. Dodatkowe materiały
Problemy z ćwiczeniami w Codelabs / opinie na ich temat
Jeśli znajdziesz jakieś problemy z tym ćwiczeniem, najpierw wyszukaj je, zanim je zgłosisz. Linki do wyszukiwania i tworzenia nowych zgłoszeń:
Materiały dotyczące migracji
Linki do folderów repozytorium dla modułu 0 (START) i modułu 15 (FINISH) znajdziesz w tabeli poniżej. Możesz też uzyskać do nich dostęp z repozytorium wszystkich migracji w ramach programu App Engine codelab, które możesz sklonować lub pobrać jako plik ZIP.
Codelab | Python 2 | Python 3 |
Część 0. | Nie dotyczy | |
Moduł 15 (to ćwiczenie) | Nie dotyczy |
Zasoby internetowe
Poniżej znajdziesz zasoby online, które mogą być przydatne w tym samouczku:
App Engine
- Usługa Blobstore w App Engine
- Limity dotyczące danych przechowywanych w App Engine
- Dokumentacja App Engine
- Środowisko wykonawcze App Engine (środowisko standardowe) dla Pythona 2
- Korzystanie z wbudowanych bibliotek App Engine w App Engine z Pythonem 2
- Ceny i limity App Engine
- Wprowadzenie platformy App Engine drugiej generacji (2018)
- Porównanie platform pierwszej i drugiej generacji
- Wsparcie długoterminowe dla starszych środowisk wykonawczych
- Repozytorium przykładowych migracji dokumentacji
- Repozytorium przykładowych migracji przesłanych przez społeczność
Google Cloud
- Python na Google Cloud Platform
- Biblioteki klienta Google Cloud dla języka Python
- Poziom „Zawsze bezpłatnie” w Google Cloud
- Google Cloud SDK (narzędzie wiersza poleceń gcloud)
- Cała dokumentacja Google Cloud
Python
- systemy szablonów Django i Jinja2,
- Platforma internetowa
webapp2 - Dokumentacja
webapp2 webapp2_extras– połączeniawebapp2_extrasDokumentacja Jinja2
Filmy
- Serverless Migration Station
- Serverless Expeditions
- Google Cloud Tech
- Zasubskrybuj Google Developers
Licencja
To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.