App Engine 位置
App Engine 具有「地區性」,這表示執行應用程式的基礎架構位於特定地區,且由 Google 代管,可為該地區內的所有區域提供備援功能。
選擇應用程式的執行地區時,請將您在延遲時間、可用性和耐用性方面的要求,做為主要考量。一般來說,您可以選擇距離您應用程式使用者最近的地區,但也應該考量App Engine 可用的位置,以及應用程式使用的其他Google Cloud 產品和服務位置。如果跨多個位置使用服務,可能會影響應用程式的延遲時間和定價。
應用程式的地區設定完成後即無法更改。
如果您已建立 App Engine 應用程式,即可執行下列任一操作來查看所在地區:
請執行
gcloud app describe
指令。開啟 Google Cloud 控制台中的 App Engine 資訊主頁。區域會顯示在頁面頂端附近。
Cloud NDB 是 Python 用戶端程式庫,可取代 App Engine NDB。App Engine NDB 可讓 Python 2 應用程式在 Datastore 資料庫中儲存及查詢資料。Cloud NDB 可讓 Python 2 和 Python 3 應用程式在相同資料庫中儲存及查詢資料,但管理這些資料庫的產品已從 Datastore 變更為 Datastore 模式的 Firestore。雖然 Cloud NDB 程式庫可以存取使用 App Engine NDB 建立的任何資料,但使用 Cloud NDB 儲存的部分結構化資料類型無法透過 App Engine NDB 存取。因此,遷移至 Cloud NDB 應視為不可逆轉的動作。
建議您先遷移至 Cloud NDB,再將應用程式升級至 Python 3。這種逐步遷移方法可讓您在整個遷移程序中維持可運作且可測試的應用程式。
Cloud NDB 旨在取代 App Engine NDB 中的功能,因此不會支援 Datastore 模式中的 Firestore 新功能。我們建議新的 Python 3 應用程式使用 Datastore 模式用戶端程式庫,而非 Cloud NDB。
如要進一步瞭解 Cloud NDB,請參閱 GitHub 上的下列頁面:
App Engine NDB 與 Cloud NDB 的比較
相似處:
- Cloud NDB 支援 App Engine NDB 支援的幾乎所有功能,方法語法僅有細微差異。
差異:
依賴 App Engine Python 2.7 特定執行階段服務的 App Engine NDB API 已更新或從 Cloud NDB 中移除。
Python 3 和 Django 的新功能已可取代
google.appengine.ext.ndb.django_middleware
。您可以只用幾行程式碼,輕鬆編寫自己的中介軟體。App Engine NDB 要求應用程式和 Datastore 資料庫位於同一個 Google Cloud 專案中,且由 App Engine 自動提供憑證。只要您適當驗證用戶端,Cloud NDB 就能存取任何專案中的 Datastore 模式資料庫。這與其他 Google CloudAPI 和用戶端程式庫一致。
Cloud NDB 不會使用 App Engine Memcache 服務快取資料。
相反地,Cloud NDB 可在由 Memorystore、Redis Labs 或其他系統管理的 Redis 記憶體內資料存放區中快取資料。雖然目前僅支援 Redis 資料儲存庫,但 Cloud NDB 已在抽象
GlobalCache
介面中概括並定義快取,可支援其他具體實作。如要存取 Memorystore for Redis,應用程式必須使用 Serverless VPC Access。
無論是 Memorystore for Redis 還是無伺服器虛擬私人雲端存取,都沒有免費方案,而且這些產品可能無法在您的應用程式所在區域使用。詳情請參閱「遷移前須知」。
如需完整的差異清單,請參閱 Cloud NDB GitHub 專案的遷移說明。
程式碼範例:
使用 App Engine NDB 執行基本資料庫作業
開始遷移前
開始遷移前:
如果您尚未設定 Python 開發環境,請使用與 Google Cloud相容的 Python 版本,並安裝測試工具來建立隔離的 Python 環境。
如果您需要快取資料,請確認應用程式的區域支援 Serverless VPC Access 和 Memorystore for Redis。
判斷是否需要快取資料
如果您的應用程式需要快取資料,請注意,Memorystore for Redis 和 Serverless VPC Access 沒有免費方案,且不支援所有Google Cloud 區域。
一般來說:
如果應用程式經常讀取相同資料,快取功能可能會降低延遲時間。
應用程式處理的要求越多,快取的影響就越大。
如要瞭解目前對快取資料的依賴程度,請查看 Memcache 資訊主頁,瞭解快取命中和未命中的比率。如果比率偏高,使用資料快取可能會對降低應用程式延遲時間產生重大影響。
如需定價資訊,請參閱 Memorystore 定價和 無伺服器虛擬私人雲端存取定價。
確認應用程式所在區域
如果您需要快取資料,請確認應用程式的所在區域支援 Memorystore for Redis 和 Serverless VPC Access:
查看應用程式的所在地區,會顯示在 Google Cloud 主控台的 App Engine 資訊主頁頂端附近。
這個區域會顯示在頁面頂端,位於應用程式網址下方。
確認應用程式位於無伺服器虛擬私有雲存取支援的地區。
請前往「建立連接器」頁面,查看「地區」清單中的地區,確認您的應用程式位於 Memorystore for Redis 支援的地區。
如果您的應用程式不在 Memorystore for Redis 和 Serverless VPC Access 支援的地區:
建立 Google Cloud 專案。
在專案中建立新的 App Engine 應用程式,然後選取支援的地區。
建立應用程式在新專案中使用的 Google Cloud 服務。
或者,您也可以更新應用程式,以便使用舊專案中的現有服務,但在不同專案和地區使用服務時,價格和資源使用情況可能會有所不同。詳情請參閱各項服務的說明文件。
將應用程式部署至新專案。
瞭解 Datastore 模式權限
您必須對每項與 Google Cloud 服務的互動進行授權。舉例來說,如要在 Datastore 模式資料庫中儲存或查詢資料,應用程式必須提供已獲授權存取資料庫的帳戶憑證。
根據預設,您的應用程式會提供 App Engine 預設服務帳戶的憑證,該帳戶已獲授權存取與應用程式相同專案中的資料庫。
如果符合下列任一條件,您就必須使用其他驗證技術,明確提供憑證:
應用程式和 Datastore 模式資料庫位於不同的Google Cloud 專案中。
您已變更指派給預設 App Engine 服務帳戶的角色。
如要瞭解其他驗證技術,請參閱「設定伺服器對伺服器正式版應用程式的驗證作業」。
轉換程序總覽
如要遷移至 Cloud NDB,請按照下列步驟操作:
-
安裝 Cloud NDB 用戶端程式庫。
更新匯入陳述式,以便從 Cloud NDB 匯入模組。
加入建立 Cloud NDB 用戶端的程式碼。用戶端可讀取應用程式的環境變數,並使用這些資料透過 Datastore 模式進行驗證。
新增使用用戶端執行階段背景的程式碼,以便在執行緒之間保持快取和交易的區隔。
移除或更新使用已不再支援的方法和屬性的程式碼。
啟用快取。
-
如同對應用程式所做的任何變更,請考慮使用流量分配功能,以便逐步增加流量。請密切監控應用程式是否有任何資料庫問題,再將更多流量導向更新版應用程式。
更新 Python 應用程式
為 Python 應用程式安裝 Cloud NDB 程式庫
如要在 App Engine Python 應用程式中安裝 Cloud NDB 用戶端程式庫,請按照下列步驟操作:
更新
app.yaml
檔案。請按照您使用的 Python 版本操作說明進行操作:Python 2
如果是 Python 2 應用程式,請新增最新版本的
grpcio
和setuptools
程式庫。以下是
app.yaml
檔案範例:runtime: python27 threadsafe: yes api_version: 1 libraries: - name: grpcio version: latest - name: setuptools version: latest
Python 3
如果是 Python 3 應用程式,請使用支援的 Python 3 版本指定
runtime
元素,並刪除不必要的列。例如,您的app.yaml
檔案可能如下所示:runtime: python310 # or another support version
Python 3 執行階段會自動安裝程式庫,因此您不需要指定先前 Python 2 執行階段內建的程式庫。如果 Python 3 應用程式在遷移時使用其他舊版內含服務,請保留
app.yaml
檔案。更新
requirements.txt
檔案。請按照您使用的 Python 版本操作說明進行操作:Python 2
將 Cloud NDB 適用的 Cloud 用戶端程式庫新增至
requirements.txt
檔案中的依附元件清單。google-cloud-ndb
接著執行
pip install -t lib -r requirements.txt
,更新應用程式可用的程式庫清單。Python 3
將 Cloud NDB 適用的 Cloud 用戶端程式庫新增至
requirements.txt
檔案中的依附元件清單。google-cloud-ndb
App Engine 會在 Python 3 執行階段的應用程式部署期間自動安裝這些依附元件,因此請刪除
lib
資料夾 (如果有)。針對 Python 2 應用程式,如果應用程式使用
lib
目錄中指定的內建或複製程式庫,則必須在appengine_config.py
檔案中指定這些路徑:import pkg_resources from google.appengine.ext import vendor # Set PATH to your libraries folder. PATH = 'lib' # Add libraries installed in the PATH folder. vendor.add(PATH) # Add libraries to pkg_resources working set to find the distribution. pkg_resources.working_set.add_entry(PATH)
請務必使用
pkg_resources
模組,確保應用程式使用正確的用戶端程式庫發行套件。上述範例中的
appengine_config.py
檔案假設lib
資料夾位於目前的工作目錄。如果您無法保證lib
一律會位於目前的工作目錄中,請指定lib
資料夾的完整路徑。例如:import os path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib')
部署應用程式時,App Engine 會上傳
appengine_config.py
檔案中指定目錄中的所有程式庫。
更新匯入陳述式
NDB 模組的位置已移至 google.cloud.ndb
。請更新應用程式的匯入陳述式,如下表所示:
移除 | 取代憑證 |
---|---|
from google.appengine.ext import ndb |
from google.cloud import ndb |
建立 Cloud NDB 用戶端
與其他以 Google Cloud API 為基礎的用戶端程式庫一樣,使用 Cloud NDB 的第一步是建立 Client
物件。用戶端包含憑證和其他連線至 Datastore 模式所需的資料。例如:
from google.cloud import ndb
client = ndb.Client()
在先前所述的預設授權情境中,Cloud NDB 用戶端包含 App Engine 預設服務帳戶的憑證,該帳戶已獲授權與 Datastore 模式互動。如果您並未使用這個預設情境,請參閱「應用程式預設憑證 (ADC)」,瞭解如何提供憑證。
使用用戶端的執行階段內容
除了提供與 Datastore 模式互動所需的憑證,Cloud NDB 用戶端還包含 context()
方法,可傳回執行階段內容。執行階段背景會將快取和交易要求與其他並行的 Datastore 模式互動隔離。
所有與 Datastore 模式的互動都必須在 NDB 執行階段內容中發生。由於建立模型定義不會與 Datastore 模式互動,因此您可以在建立 Cloud NDB 用戶端及擷取執行階段背景資訊之前,先定義模型類別,然後在要求處理常式中使用執行階段背景資訊,從資料庫取得資料。
例如:
多執行緒應用程式
Cloud NDB 用戶端傳回的執行階段背景資訊僅適用於單一執行緒。如果應用程式為單一要求使用多個執行緒,您需要為每個會使用 Cloud NDB 程式庫的執行緒,擷取個別的執行階段背景。
搭配 WSGI 架構使用執行階段內容
如果網頁應用程式使用 WSGI 架構,您可以建立可擷取執行階段內容的 middleware 物件,然後將應用程式包裝在 middleware 物件中,為每個要求自動建立新的執行階段內容。
以下範例說明如何搭配 Flask 使用中介軟體:
middleware
方法會在 NDB 用戶端的執行階段情境中建立 WSGI 中介軟體物件。Flask 應用程式會包裝在中介軟體物件中。
接著,Flask 會將每項要求傳遞至中介軟體物件,後者會為每項要求擷取新的 NDB 執行階段情境。
在 Django 中使用執行階段背景資訊
Cloud NDB 程式庫不支援 App Engine NDB 程式庫提供的 Django 中介軟體。如果您在應用程式中使用此中介軟體 (google.appengine.ext.ndb.django_middleware
),請按照下列步驟更新應用程式:
使用 Django 的中介軟體系統,為每項要求建立新的執行階段內容。
在下列範例中:
ndb_django_middleware
方法會建立 Cloud NDB 用戶端。middleware
方法會在 NDB 用戶端的執行階段情境中建立中介軟體物件。
在 Django settings.py 檔案中,更新
MIDDLEWARE
設定,讓系統列出您建立的新中介軟體,而非google.appengine.ext.ndb.NdbDjangoMiddleware
。
Django 現在會將每個要求傳送至您在 MIDDLEWARE
設定中列出的中介軟體物件,而這個物件會為每個要求擷取新的 NDB 執行階段內容。
針對已移除或變更的 NDB API 更新程式碼
依賴 App Engine 專屬 API 和服務的 NDB API 已更新,或已從 Cloud NDB 程式庫中移除。
如果程式碼使用下列任何 NDB API,就必須進行更新:
google.appengine.ext.ndb.Model
和模型屬性google.appengine.ext.ndb.Key
google.appengine.ext.ndb.query.QueryOptions
和PropertyOrder
google.appengine.ext.ndb.utils
google.appengine.api.namespacemanager
google.appengine.api.ext.ndb.tasklets
google.appengine.api.datastore_errors
模型和模型屬性
以下來自 google.appengine.ext.ndb.Model
的方法無法在 Cloud NDB 程式庫中使用,因為這些方法使用的是已停用的 App Engine 專屬 API。
已移除的 API | 替換 |
---|---|
Model.get_indexes 和 Model.get_indexes_async
|
無 |
Model._deserialize 和 Model._serialize
|
無 |
Model.make_connection
|
無 |
下表說明 Cloud NDB 程式庫中已變更的特定 google.appengine.ext.ndb.Model
屬性:
屬性 | 變更 |
---|---|
TextProperty
|
google.cloud.ndb.TextProperty 無法建立索引。如果您嘗試設定 google.cloud.ndb.TextProperty.indexed ,系統會引發 NotImplementedError 。 |
StringProperty
|
StringProperty 一律會編入索引。如果您嘗試設定 google.cloud.ndb.StringProperty.indexed ,系統會引發 NotImplementedError 。 |
在建構函式中,所有具有 name 或 kind 引數的屬性。 |
name 或 kind 必須是 str 資料類型,因為 unicode 已在 Python 3 中由 str 取代。 |
下表中的類別和方法已不再提供,因為這些類別和方法使用了已停用的 App Engine 專屬資源。
已移除的 API | 替換 |
---|---|
google.appengine.ext.ndb.msgprop.MessageProperty 和 google.appengine.ext.ndb.msgprop.EnumProperty
|
無
如果您嘗試建立這些物件,系統會擲回 |
來自
google.appengine.ext.ndb.model.Property :_db_get_value _db_set_value _db_set_compressed_meaning _db_set_uncompressed_meaning __creation_counter_global
|
無
這些方法會依賴已變更的 Datastore 模式通訊協定緩衝區。 |
Model.make_connection
|
無 |
金鑰
以下 google.appengine.ext.ndb.Key
的方法不適用於 Cloud NDB 程式庫。這些方法用於將金鑰傳遞至 DB Datastore API 和從中傳遞,但該 API 已不再支援 (DB 是 App Engine NDB 的前身)。
已移除的 API | 替換 |
---|---|
Key.from_old_key 和 Key.to_old_key
|
無 |
此外,請注意下列變更:
App Engine NDB | Cloud NDB |
---|---|
Kinds 和字串 ID 長度不得超過 500 個位元組 | Kind 和字串 ID 不得超過 1500 個位元組。 |
Key.app() 會傳回您在建立金鑰時指定的專案 ID。 |
google.cloud.ndb.Key.app() 傳回的值可能與傳入建構函式的原始 ID 不同。這是因為 s~example 等前置應用程式 ID 是 App Engine 的舊版 ID。已由等效的專案 ID 取代,例如 example。 |
查詢
與 App Engine NDB 一樣,Cloud NDB 也提供 QueryOptions
類別 (google.cloud.ndb.query.QueryOptions
),可讓您重複使用特定一組查詢選項,而非為每項查詢重新定義。不過,Cloud NDB 中的 QueryOptions
不會繼承 google.appengine.datastore.datastore_rpc.Configuration
,因此不支援 ...datastore_rpc.Configuration
方法。
此外,google.appengine.datastore.datastore_query.Order
已替換為 google.cloud.ndb.query.PropertyOrder
。與 Order
類似,PropertyOrder
類別可讓您指定多個查詢的排序順序。PropertyOrder
建構函式與 Order
的建構函式相同。只有類別名稱有所變更。
已移除的 API | 替換 |
---|---|
from google.appengine.datastore.datastore_rpc.Configuration :deadline(value) on_completion(value) read_policy(value) force_writes(value) max_entity_groups_per_rpc(value) max_allocate_ids_keys(value) max_rpc_bytes(value) max_get_keys(value) max_put_entities(value) max_delete_keys(value)
如要瞭解這些方法,請參閱原始碼。 |
無 |
google.appengine.ext.ndb.Order (例如) order=Order(-Account.birthday, Account.name)
|
google.cloud.ndb.PropertyOrder 例如: google.cloud.ndb.PropertyOrder(-Account.birthday, Account.name)
|
Utils
ndb.utils
模組 (google.appengine.ext.ndb.utils
) 已不再提供。該模組中的大多數方法都是 App Engine NDB 內部方法,部分方法已因新 ndb 的實作差異而遭到淘汰,其他方法則因新 Python 3 功能而淘汰。
舉例來說,舊版 utils
模組中的位址修飾符宣告,只有函式或方法的前 n 個引數可以是位址。不過,Python 3 可以使用僅關鍵字引數執行這項操作。原本的寫法如下:
@utils.positional(2)
def function1(arg1, arg2, arg3=None, arg4=None)
pass
在 Python 3 中可以這麼寫:
def function1(arg1, arg2, *, arg3=None, arg4=None)
pass
命名空間
命名空間可讓多租戶架構應用程式在使用相同 Datastore 模式資料庫的情況下,為每個用戶群取用各自獨立的資料孤島。也就是說,每個租用戶都會在自己的命名空間中儲存資料。
您在建立 Cloud NDB 用戶端時,不使用 App Engine 專屬的 google.appengine.api.namespacemanager
,而是指定預設命名空間,然後在用戶端的執行階段內容中呼叫 Cloud NDB 方法,以便使用預設命名空間。這與支援命名空間的其他 Google CloudAPI 採用相同的模式。
已移除的 API | 替換 |
---|---|
google.appengine.api.namespace_manager.namespace_manager.set_namespace(str)
和 google.appengine.api.namespacemanager.getnamespace()
|
client=google.cloud.ndb.Client(namespace="my namespace") with client.context() as context: key = ndb.Key("SomeKind", "SomeId") key-non-default-namespace=ndb.Key("SomeKind," "AnotherId", namespace="non-default-nspace") |
所有其他 google.appengine.api.namespacemanager 方法 |
無 |
Tasklet
Tasklet 現在可以使用標準 return
陳述式來傳回結果,而非擲回 Return
例外狀況。例如:
App Engine NDB 程式庫 | Cloud NDB 程式庫 |
---|---|
@ndb.tasklet def get_cart(): cart = yield CartItem.query().fetch_async() raise Return(cart) |
@ndb.tasklet def get_cart(): cart = yield CartItem.query().fetch_async() return cart |
請注意,您仍可透過觸發 Return
例外狀況,在 Cloud NDB 中傳回結果,但不建議這麼做。
此外,下列 Tasklets
方法和子類別已無法使用,主要是因為 Cloud NDB 程式庫中建立及使用 NDB 情境的方式有所變更。
已移除的 API | 替換 |
---|---|
來自
google.appengine.api.ext.ndb.tasklets :add_flow_exception make_context make_default_context set_context
|
無 |
來自
google.appengine.api.ext.ndb.tasklets :QueueFuture ReducedFuture SerialQueueFuture
|
無 |
例外狀況
雖然 Cloud NDB 程式庫中的 google.cloud.ndb.exceptions
模組包含許多與 App Engine NDB 程式庫相同的例外狀況,但並非所有舊例外狀況都能在新程式庫中使用。下表列出不再支援的例外狀況:
已移除的 API | 替換 |
---|---|
來自
google.appengine.api.datastore_errors :BadKeyError BadPropertyError CommittedButStillApplying EntityNotFoundError InternalError NeedIndexError QueryNotFoundError ReferencePropertyResolveError Timeout TransactionFailedError TransactionNotFoundError
|
google.cloud.ndb.exceptions |
啟用資料快取
Cloud NDB 可在由 Memorystore、Redis Labs 或其他系統管理的 Redis 記憶體內資料儲存庫中快取資料。本指南說明如何使用 Memorystore for Redis 快取資料:
設定無伺服器虛擬私有雲存取
應用程式只能透過無伺服器虛擬私人雲端存取連接器與 Memorystore 通訊。如要設定無伺服器虛擬私有雲存取連接器,請按照下列步驟操作:
設定 Memorystore for Redis
如要設定 Memorystore for Redis,請按照下列步驟操作:
在 Memorystore 中建立 Redis 執行個體。建立執行個體時:
在「Region」下方,選取 App Engine 應用程式所在的相同地區。
在「Authorized network」(授權網路) 下方,選取無伺服器虛擬私有雲端存取連接器使用的網路。
請記下您建立的 Redis 執行個體的 IP 位址和通訊埠編號。您會在為 Cloud NDB 啟用資料快取功能時使用這項資訊。
請務必使用
gcloud beta
指令部署應用程式更新。只有 beta 指令可以更新應用程式,以便使用 VPC 連接器。
新增 Redis 連線網址
您可以將 REDIS_CACHE_URL
環境變數新增至應用程式的 app.yaml
檔案,藉此連線至 Redis 快取。REDIS_CACHE_URL
的值採用以下格式:
redis://IP address for your instance:port
舉例來說,您可以將下列程式碼新增至應用程式的 app.yaml
檔案:
env_variables:
REDIS_CACHE_URL: redis://10.0.0.3:6379
建立及使用 Redis 快取物件
如果您已將 REDIS_CACHE_URL
設為環境變數,可以使用單行程式碼建立 RedisCache 物件,然後在設定執行階段內容時,將快取傳遞至 Client.context()
以便使用快取:
client = ndb.Client()
global_cache = ndb.RedisCache.from_environment()
with client.context(global_cache=global_cache):
books = Book.query()
for book in books:
print(book.to_dict())
如果您未將 REDIS_CACHE_URL
設為環境變數,就必須建構 Redis 用戶端,並將用戶端傳遞至 ndb.RedisCache()
建構函式。例如:
global_cache = ndb.RedisCache(redis.StrictRedis(host=IP-address, port=redis_port))
請注意,您不需要宣告對 Redis 用戶端程式庫的依附元件,因為 Cloud NDB 程式庫已依附 Redis 用戶端程式庫。
如需建構 Redis 用戶端的範例,請參閱 Memorystore 範例應用程式。
測試更新
如要設定測試資料庫,並在本機執行應用程式,然後再將應用程式部署至 App Engine,請按照下列步驟操作:
執行 Datastore 模式的本機模擬器,以便儲存及擷取資料。
請務必按照設定環境變數的操作說明操作,讓應用程式連線至模擬器,而非實際運作的 Datastore 模式環境。
如果您想先將資料預先載入資料庫,再開始測試,也可以將資料匯入模擬器。
使用本機開發伺服器執行應用程式。
如要確保在本機開發期間正確設定
GOOGLE_CLOUD_PROJECT
環境變數,請使用下列參數初始化dev_appserver
:--application=PROJECT_ID
將 PROJECT_ID 替換為您的 Google Cloud 專案 ID。您可以執行
gcloud config list project
指令,或在 Google Cloud 主控台中查看專案頁面,找出專案 ID。
部署您的應用程式
應用程式在本機開發伺服器中執行時,如果沒有發生錯誤,請按照下列步驟操作:
如果應用程式執行時沒有發生錯誤,請使用流量分配功能,逐步增加更新後應用程式的流量。在將更多流量導向更新後的應用程式前,請密切監控應用程式是否有任何資料庫問題。
後續步驟
- 如需實作教學課程,請參閱從 App Engine ndb 遷移至 Cloud NDB 程式碼研究室。
- 詳情請參閱 Cloud NDB 說明文件。