1. 概要
この一連の Codelab(セルフペース型のハンズオン チュートリアル)は、Google App Engine(スタンダード環境)のデベロッパーが一連の移行手順をご案内し、アプリをモダナイズできるようにすることを目的としています。最も大きなステップは、元のランタイム バンドル サービスから移行することです。理由は、次世代のランタイムが柔軟性に富み、ユーザーにさまざまなサービス オプションが提供されるためです。新しい世代のランタイムに移行することで、Google Cloud プロダクトとの統合が容易になり、幅広いサポート対象サービスを使用し、現在の言語リリースをサポートできるようになります。
このオプションのチュートリアルでは、Datastore サービスと通信するために、Cloud NDB から Cloud Datastore をクライアント ライブラリとして移行する方法をデベロッパーに説明します。NDB は Python 3 と互換性があるため、NDB を使い続ける場合もあるでしょう。そのため、この移行は任意です。この移行は、すでに Cloud Datastore を使用している他のアプリとの間で一貫したコードベースと共有ライブラリを構築したいユーザーのみを対象としています。これについては「背景情報」。
方法を学ぶ対象
- Cloud NDB を使用する(使い慣れていない場合)
- Cloud NDB から Cloud Datastore に移行する
- Python 3 へのアプリの移行をさらに進める
必要なもの
- 有効な GCP 請求先アカウントを持つ Google Cloud Platform プロジェクト
- 基本的な Python スキル
- 基本的な Linux コマンドに関する実用的な知識がある
- App Engine アプリの開発とデプロイに関する基本的な知識
- 機能するモジュール 2 の App Engine 2.x または 3.x アプリ。
アンケート
この Codelab をどのように使用されますか?
<ph type="x-smartling-placeholder">2. 背景情報
Cloud NDB は、長年の App Engine デベロッパーにとって優れた Datastore ソリューションであり、Python 3 への移行に役立ちますが、App Engine デベロッパーが Datastore にアクセスする方法はこれだけではありません。App Engine の Datastore が 2013 年に独自のプロダクトとなった Google Cloud Datastore では、すべてのユーザーが Datastore を使用できるように、新しいクライアント ライブラリが作成されました。
Python 3 App Engine 開発者と App Engine 以外の開発者は、(Cloud NDB ではなく)Cloud Datastore を使用するよう指示されます。Python 2 App Engine のデベロッパーは、ndb
から Cloud NDB に移行し、そこから Python 3 に移植することが推奨されていますが、さらに Cloud Datastore に移行することもできます。特に、先ほど挙げたような Cloud Datastore を使用するコードがあり、すべてのアプリケーションに共有ライブラリを作成したいと考えているデベロッパーにとって、これは当然のことです。コードの再利用はコードの整合性と同様にベスト プラクティスであり、以下に示すように、どちらも全体的なメンテナンス費用の削減に役立ちます。
Cloud NDB から Cloud Datastore への移行
- デベロッパーは Datastore にアクセスする単一のコードベースに集中できる
- Cloud NDB を使用するコードもあれば、Cloud Datastore を使用するコードのメンテナンスも不要
- コードベースの一貫性を高め、コードの再利用性を高める
- 共通/共有ライブラリを使用できるため、全体的なメンテナンス費用を削減できます。
この移行の主なステップは次のとおりです。
- セットアップ / 事前作業
- Cloud NDB を Cloud Datastore クライアント ライブラリに置き換える
- アプリケーションの更新
3. 設定/事前作業
チュートリアルの主要部分に進む前に、まずプロジェクトをセットアップし、コードを取得してから、ベースライン アプリをデプロイします。これで、作業コードを使って作業を開始できます。
1. プロジェクトのセットアップ
モジュール 2 の Codelab を修了した場合は、同じプロジェクト(およびコード)を再利用することをおすすめします。または、新しいプロジェクトを作成するか、別の既存のプロジェクトを再利用することもできます。プロジェクトにアクティブな請求先アカウントがあり、App Engine(アプリ)が有効になっていることを確認します。
2. ベースラインのサンプルアプリを取得する
前提条件の 1 つは、機能するモジュール 2 サンプルアプリがあることです。このチュートリアルを完了している場合は、ソリューションを使用します。今すぐ完了できます(上のリンク)。スキップする場合は、モジュール 2 のリポジトリ(以下のリンク)をコピーします。
使用するコードにかかわらず、モジュール 2 のコードから開始します。このモジュール 3 の Codelab では各ステップを説明します。完了すると、FINISH ポイントのコードに似ています。このチュートリアルには Python 2 バージョンと Python 3 バージョンがあるため、以下の正しいコード リポジトリを確認してください。
Python 2
- 開始: モジュール 2 コード
- 終了: モジュール 3 のコード
- リポジトリ全体(クローン作成または ZIP をダウンロード)
Python 2 モジュール 2 の開始ファイル(独自のまたは Google のもの)のディレクトリは次のようになります。
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
モジュール 2 のチュートリアルを完了したら、Flask とその依存関係を含む lib
フォルダも作成されます。lib
フォルダがない場合は、次のステップでこのベースライン アプリをデプロイできるように、pip install -t lib -r requirements.txt
コマンドを使用して作成します。Python 2 と Python 3 の両方をインストールしている場合は、Python 3 との混乱を避けるため、pip
ではなく pip2
を使用することをおすすめします。
Python 3
- 開始: モジュール 2 リポジトリ
- 終了: モジュール 3 リポジトリ
- リポジトリ全体(クローン作成または ZIP をダウンロード)
Python 3 モジュール 2 開始ファイルのディレクトリ(ご自身または私たちのもの)は次のようになります。
$ ls
README.md main.py templates
app.yaml requirements.txt
Python 3 では、lib
も appengine_config.py
も使用されません。
3. モジュール 2 アプリを(再)デプロイする
この段階で実施する必要がある残りの事前作業のステップ:
gcloud
コマンドライン ツールについて復習します(必要な場合)。- モジュール 1 コードを App Engine に(再)デプロイします(必要な場合)。
各手順を正常に実行して、動作していることを確認したら、このチュートリアルに進み、構成ファイルを使用して作業を開始します。
4. Cloud NDB を Cloud Datastore クライアント ライブラリに置き換える
唯一の構成変更は、requirements.txt
ファイルでのパッケージのマイナー スワップです。
1. requirements.txt
の更新
モジュール 2 を完了すると、requirements.txt
ファイルは次のようになります。
- 変更前(Python 2 および 3):
Flask==1.1.2
google-cloud-ndb==1.7.1
Cloud NDB ライブラリ(google-cloud-ndb
)を最新バージョンの Cloud Datastore ライブラリ(google-cloud-datastore
)に置き換え、Flask のエントリはそのままにして requirements.txt
を更新します。Python 2 と互換性のある Cloud Datastore の最終バージョンは 1.15.3 であることに注意してください。
- 変更後(Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
- 変更後(Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0
リポジトリはこのチュートリアルよりも定期的にメンテナンスされるため、requirements.txt
ファイルに新しいバージョンが反映されている可能性があります。各ライブラリの最新バージョンを使用することをおすすめしますが、それでも問題が解決しない場合は、古いリリースにロールバックできます。上記のバージョン番号は、この Codelab の最終更新日時です。
2. その他の構成ファイル
他の構成ファイル(app.yaml
と appengine_config.py
)は、前の移行手順と同じである必要があります。
app.yaml
は、引き続きサードパーティのバンドル パッケージgrpcio
とsetuptools
を参照する必要があります。appengine_config.py
は(引き続き)pkg_resources
とgoogle.appengine.ext.vendor
がlib
内のサードパーティ リソースを指すようにする必要があります。
次は、アプリケーションのファイルに移りましょう。
5. アプリケーション ファイルを更新する
template/index.html
に変更はありませんが、main.py
に変更がいくつか加えられています。
1. インポート
import セクションの開始コードは次のようになります。
- 変更前:
from flask import Flask, render_template, request
from google.cloud import ndb
google.cloud.ndb
インポートを Cloud Datastore のインポート(google.cloud.datastore
)に置き換えます。Datastore クライアント ライブラリではエンティティ内のタイムスタンプ フィールドの自動作成がサポートされていないため、標準ライブラリ datetime
モジュールもインポートして手動で作成します。慣例として、標準のライブラリ インポートはサードパーティ パッケージ インポートよりも優先されます。これらの変更が完了すると、次のようになります。
- 変更後:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore
2. 初期化とデータモデル
Flask を初期化した後、モジュール 2 サンプルアプリは NDB データモデル クラスとそのフィールドを次のように作成します。
- 変更前:
app = Flask(__name__)
ds_client = ndb.Client()
class Visit(ndb.Model):
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
Cloud Datastore ライブラリにはそのようなクラスがないため、Visit
クラス宣言を削除してください。Datastore と通信するには引き続きクライアントが必要であるため、ndb.Client()
を datastore.Client()
に変更します。Datastore ライブラリはより「柔軟性」が高く、「事前宣言」なしでエンティティを作成できるその構造を使用します。この更新後、main.py
のこの部分は次のようになります。
- 変更後:
app = Flask(__name__)
ds_client = datastore.Client()
3. Datastore アクセス
Cloud Datastore に移行するには、Datastore エンティティの作成、保存、クエリの方法を(ユーザーレベルで)変更する必要があります。アプリケーションの場合、Datastore コードの複雑さによって、移行が難しくなる場合があります。サンプルアプリでは、できる限り簡単に更新できるようにしました。出発点のコードは次のとおりです。
- 変更前:
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])
Cloud Datastore で汎用エンティティを作成し、エンティティ内のグループ化されたオブジェクトを「キー」で識別します。Key-Value ペアの JSON オブジェクト(Python dict
)を使用してデータレコードを作成し、想定される put()
を使用して Datastore に書き込みます。Datastore ではクエリと似ていますが、より簡単です。同等の Datastore コードの違いを次に示します。
- 変更後:
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)
上記のように store_visit()
と fetch_visits()
の関数本体を更新し、署名は以前のバージョンと同じままにします。メインハンドラ root()
に変更はありません。これらの変更が完了すると、アプリは Cloud Datastore を使用する準備が整い、テストの準備が整いました。
6. 概要/クリーンアップ
アプリケーションのデプロイ
gcloud app deploy
を使用してアプリを再デプロイし、アプリが動作していることを確認します。コードがモジュール 3 のリポジトリ フォルダの内容と一致するはずです。
先行するいずれの Codelab の取り組みも行わずにこのシリーズに進んだ場合、アプリ自体は変更されません。このアプリは、メインのウェブページ(/
)へのすべての訪問を登録します。一定回数以上サイトにアクセスすると、ウェブページは次のように表示されます。
以上で、モジュール 3 の Codelab は完了です。これで、Cloud NDB と Cloud Datastore の両方のクライアント ライブラリを使用して Datastore にアクセスできることを確認しました。後者に移行することで、共有ライブラリ、共通のコードやコードの再利用による一貫性、メンテナンス費用の削減といったメリットを享受できます。
オプション: クリーンアップ
次の移行 Codelab に進む準備が整うまで、課金されるのを回避するためのクリーンアップを行うにはどうすればよいでしょうか。既存のデベロッパーの方は、App Engine の料金に関する情報に関する最新の内容をすでにご存じと思われます。
オプション: アプリを無効にする
次のチュートリアルに進む準備がまだ完了していない場合は、アプリを無効にすることで課金されないようにできます。次の Codelab に進む準備ができた時点で、再度有効にできます。アプリが無効になっている間、料金のかかるトラフィックは発生しません。ただし、もう 1 つの課金対象は、Datastore の使用量です。無料割り当て量を超過した場合は課金が発生するため、上限を超えないよう削除してください。
ただし、移行を続けず、すべてを完全に削除する場合は、プロジェクトをシャットダウンしてください。
次のステップ
ここからは、次の移行モジュールを自由にお楽しみください。
- モジュール 3 参考: 参考セクションに進み、Python 3 と次世代の App Engine ランタイムに移行する方法をご確認ください。
- モジュール 7: App Engine の push タスクキュー([push] タスクキューを使用する場合に必要)
- App Engine
taskqueue
プッシュタスクをモジュール 1 アプリに追加する - モジュール 8 で Cloud Tasks に移行するユーザーの準備を行う
- App Engine
- モジュール 4: Docker を使用して Cloud Run に移行する
- Docker を使用して、Cloud Run で実行できるようにアプリをコンテナ化します。
- Python 2 を引き続き使用できるようにする
- モジュール 5: Cloud Buildpacks を使用して Cloud Run に移行する
- Cloud Build を使用して Cloud Run で実行するようにアプリをコンテナ化します。
- Docker、コンテナ、
Dockerfile
について何も理解する必要がない - アプリを Python 3 に移行済みであることが必要です
- モジュール 6: Cloud Firestore への移行。
- Cloud Firestore に移行して Firebase の機能にアクセスします。
- Cloud Firestore は Python 2 をサポートしていますが、この Codelab は Python 3 でのみ使用できます。
7. 参考: Python 3 に移行する
最新の App Engine のランタイムと機能にアクセスするには、Python 3 に移行することをおすすめします。サンプルアプリでは、Datastore は使用した唯一の組み込みサービスでした。ndb
から Cloud NDB に移行したため、App Engine の Python 3 ランタイムに移植できるようになりました。
概要
Python 3 への移植は Google Cloud チュートリアルでは取り上げませんが、Codelab のこの部分では、Python 3 App Engine ランタイムの相違点についてデベロッパーの皆さんに説明します。次世代ランタイムの優れた機能の一つは、サードパーティ パッケージへのアクセスが簡素化されることです。app.yaml
で組み込みパッケージを指定する必要がなく、非組み込みライブラリをコピーまたはアップロードしたりする必要はありません。requirements.txt
にリストされない状態で暗黙的にインストールされます。
このサンプルは非常に基本的なものであり、Cloud Datastore は Python 2 ~ 3 と互換性があるため、アプリケーション コードを 3.x に明示的に移植する必要はありません。アプリはそのまま 2.x と 3.x で動作します。つまり、必要な変更は構成にのみ行います。
- Python 3 を参照するように
app.yaml
を簡素化し、バンドルされたサードパーティ ライブラリへの参照を削除します。 - 不要になった時点で
appengine_config.py
フォルダとlib
フォルダを削除します。
main.py
と templates/index.html
のアプリケーション ファイルは変更されません。
requirements.txt
の更新
Python 2 をサポートする Cloud Datastore の最終バージョンは 1.15.3 です。Python 3 の最新バージョン(現時点では新しい可能性があります)で requirements.txt
を更新します。このチュートリアルの作成時点では、最新バージョンは 2.1.0 でした。そのため、この行を次のように編集します(または最新バージョンになります)。
google-cloud-datastore==2.1.0
app.yaml
を簡略化する
変更前:
このサンプルアプリに対して実際に行った唯一の変更は、app.yaml
を大幅に短縮したことです。モジュール 3 の最後にある app.yaml
の内容を思い出してください。
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
変更後:
Python 3 では、threadsafe
、api_version
、libraries
ディレクティブはすべて非推奨になりました。すべてのアプリはスレッドセーフと想定されており、api_version
は Python 3 では使用されません。App Engine サービスにサードパーティ パッケージがプリインストールされなくなったため、libraries
も非推奨になりました。これらの変更について詳しくは、app.yaml
の変更に関するドキュメントをご覧ください。そのため、app.yaml
から 3 つすべてを削除し、サポートされている Python 3 バージョンに更新する必要があります(以下を参照)。
省略可: handlers
ディレクティブの使用
さらに、App Engine アプリケーションにトラフィックを転送する handlers
ディレクティブも非推奨になりました。次世代のランタイムはウェブ フレームワークがアプリのルーティングを管理することを想定しているため、すべての「ハンドラ スクリプト」「auto
」に変更する必要があります。上記での変更を組み合わせると、次の app.yaml
になります。
runtime: python38
handlers:
- url: /.*
script: auto
script: auto
の詳細については、app.yaml
リファレンス ページをご覧ください。
handlers
ディレクティブの削除
handlers
はサポートが終了しているため、app.yaml
の 1 行を残してセクション全体を削除することもできます。
runtime: python38
これによってデフォルトでは、すべてのアプリケーションで使用可能な Gunicorn WSGI ウェブサーバーが起動されます。gunicorn
に精通されている場合は、このコマンドがベアボーン app.yaml
で最初に起動すると実行されます。
gunicorn main:app --workers 2 -c /config/gunicorn.py
省略可: entrypoint
ディレクティブの使用
ただし、アプリケーションで特定の起動コマンドが必要な場合は、entrypoint
ディレクティブで指定すると、app.yaml
は次のようになります。
runtime: python38
entrypoint: python main.py
この例では、gunicorn
の代わりに Flask 開発用サーバーを使用することを明示的にリクエストします。開発用サーバーを起動するコードもアプリに追加して、ポート 8080 の 0.0.0.0
インターフェースで起動されるようにする必要があります。そのためには、次の小さなセクションを main.py
の下部に追加します。
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
entrypoint
の詳細については、app.yaml
リファレンス ページをご覧ください。その他の例とベスト プラクティスについては、App Engine スタンダード環境の起動ドキュメントと App Engine フレキシブル環境の起動ドキュメントをご覧ください。
appengine_config.py
と lib
を削除します。
appengine_config.py
ファイルと lib
フォルダを削除します。Python 3 への移行では、App Engine は requirements.txt
にリストされているパッケージを取得してインストールします。
appengine_config.py
構成ファイルは、サードパーティのライブラリまたはパッケージを、ご自分でコピーしたか、App Engine サーバーですでに使用可能なもの(組み込み)を使用しているかを認識するために使用されます。Python 3 に移行する際の、大きな変更の概要は次のとおりです。
- コピーされたサードパーティ ライブラリのバンドルはありません(
requirements.txt
に記載) lib
フォルダにpip install
が含まれていない(つまり、lib
フォルダのピリオドがない)app.yaml
に組み込みのサードパーティ ライブラリが記載されていない- サードパーティのライブラリにアプリを参照する必要はないため、
appengine_config.py
ファイルは不要
必要であるのは、すべてのサードパーティ ライブラリを requirements.txt
に記載することのみです。
アプリケーションのデプロイ
再デプロイしてアプリが動作するようにします。また、ソリューションがモジュール 3 の Python 3 コードのサンプルにどれだけ近いかを確認することもできます。Python 2 との相違を可視化するには、コードを Python 2 バージョンと比較します。
おめでとうございます。モジュール 3 のボーナス ステップを完了しました。Python 3 ランタイム用の構成ファイルの準備に関するドキュメントをご覧ください。最後に、前述のまとめを振り返り、次のステップとクリーンアップを行います。
ご自分のアプリケーションを準備する
アプリケーションを移行する際は、main.py
とその他のアプリケーション ファイルを 3.x に移植する必要があります。そのため、可能な限り 2.x アプリケーションを「前方互換性」を有するものにすることをおすすめします。
これを実現するうえで有用なオンライン リソースは多数ありますが、重要なヒントをいくつか紹介します。
- すべてのアプリケーションの依存関係が 3.x と完全互換であることを確認します。
- アプリケーションが 2.6 以上で実行されるようにします(推奨は 2.7)。
- アプリケーションがテストスイート全体(および 80% 以上のカバレッジ)に合格していることを確認します。
six
、Future、Modernize などの互換性ライブラリを使用します。- 下位互換性のない主な 2.x と 3.x の相違について認識します。
- どのような I/O でも、Unicode とバイト文字列の非互換性が発生する可能性が高い
サンプルアプリは、これらすべてを念頭に置いて設計されました。そのため、アプリは 2.x と 3.x で初期設定の状態で実行できます。これにより、次世代プラットフォームを使用するために変更が必要な箇所を示すことにフォーカスできます。
8. 参考情報
App Engine 移行モジュールの Codelab に関する問題 / フィードバック
この Codelab に問題が見つかった場合は、提出する前にまず問題を検索してください。新しい問題の検索と登録を行うためのリンク:
移行に関するリソース
以下の表に、モジュール 2(START)とモジュール 3(FINISH)のリポジトリ フォルダへのリンクを示します。また、これらのファイルには、すべての App Engine 移行のリポジトリからアクセスすることもできます。このクローンの作成や ZIP ファイルのダウンロードも可能です。
Codelab | Python 2 | Python 3 |
モジュール 3 |
App Engine リソース
この特定の移行に関する追加リソースは以下のとおりです。
- Python の Cloud NDB と Cloud Datastore のリファレンス
- Python 3 および GAE 次世代ランタイムへの移行
- 全般