在 Cloud Datastore 中儲存資料

這部分的 Python 留言板程式碼逐步操作會說明如何在 Cloud Datastore 中儲存結構化資料。只要使用 App Engine 和 Cloud Datastore,就不用擔心資料的分佈、複製以及負載平衡。透過簡單的 API 就能完成上述作業,還可以讓您獲得強大的查詢引擎和交易功能。

本頁面是多頁教學課程的一部分。如要從頭開始,並查看設定的操作說明,請前往建立留言板頁面。

儲存提交的問候語

Cloud Datastore 中寫入資料的物件稱為實體。每個實體都擁有辨識用的一組不重複金鑰。一個實體可以選擇性指派另一個實體做為「父項」,這個實體就是該父項實體的「子項」。資料儲存庫中的實體會因此形成階層結構體系,類似於檔案系統的目錄結構。詳情請參閱建立資料結構以達到嚴格的一致性一文。

App Engine 內含 Python 專用的資料模型 API,如果要使用資料模型 API,範例應用程式會匯入 google.appengine.ext.ndb 模組。每個問候語內有作者姓名、訊息內容以及張貼訊息的日期和時間。應用程式會依照時間先後顯示訊息。下列程式碼會定義資料模型:

class Author(ndb.Model):
    """Sub model for representing an author."""
    identity = ndb.StringProperty(indexed=False)
    email = ndb.StringProperty(indexed=False)

class Greeting(ndb.Model):
    """A main model for representing an individual Guestbook entry."""
    author = ndb.StructuredProperty(Author)
    content = ndb.StringProperty(indexed=False)
    date = ndb.DateTimeProperty(auto_now_add=True)

此程式碼用三個屬性來定義 Greeting 模型:author 的值為 Author 物件,含有電子郵件地址和作者的身分資料,而 content 的值為字串,date 的值則為 datetime.datetime

有些屬性建構函式會採用參數來進一步設定行為。傳送 ndb.StringProperty 建構函式 indexed=False 參數表示這個屬性的值不會編入索引。因為這個應用程式一定不會在查詢中使用此屬性,如此一來就可省下不必要的寫入作業。傳送 ndb.DateTimeProperty 建構函式的 auto_now_add=True 參數會將模型設為自動提供新物件建立的 datetime 時間戳記 (如果應用程式未另外提供一個值)。如需屬性類型和選項的完整清單,請參閱 NDB 屬性

這個應用程式使用資料模型來建立新的 Greeting 物件,然後將新物件放到 Cloud Datastore。Guestbook 處理常式會建立新問候語,並將這些問候語儲存於資料儲存庫:

class Guestbook(webapp2.RequestHandler):

    def post(self):
        # We set the same parent key on the 'Greeting' to ensure each
        # Greeting is in the same entity group. Queries across the
        # single entity group will be consistent. However, the write
        # rate to a single entity group should be limited to
        # ~1/second.
        guestbook_name = self.request.get('guestbook_name',
                                          DEFAULT_GUESTBOOK_NAME)
        greeting = Greeting(parent=guestbook_key(guestbook_name))

        if users.get_current_user():
            greeting.author = Author(
                    identity=users.get_current_user().user_id(),
                    email=users.get_current_user().email())

        greeting.content = self.request.get('content')
        greeting.put()

        query_params = {'guestbook_name': guestbook_name}
        self.redirect('/?' + urllib.urlencode(query_params))

Guestbook 處理常式會建立新 Greeting 物件,並以使用者張貼的資料來設定此物件的 authorcontent 屬性。Greeting 的父項是 Guestbook 實體,在將 Guestbook 設定為另一個實體的父項之前,不用先建立該實體。在本例中,父項的用途為了交易和一致性而設的預留位置。詳情請參閱交易記錄頁面。擁有共同祖項的物件就屬於同一個實體群組。程式碼不會設定 date 屬性,因此 date 會使用 auto_now_add=True 自動設定為目前時間。

最後,greeting.put() 會將新物件儲存到資料儲存庫中。如果已從某項查詢中取得這個物件,put() 就會更新現有的物件。因為我們使用了模型建構函式來建立這個物件,所以 put() 會將新物件加到資料儲存庫中。

只有在實體群組中,Cloud Datastore 中的資料查詢才會同步一致,因此程式碼會把每個問候語的父系設為相同,以便將整本留言板的問候語指派給同一個實體群組。這樣一來,使用者會在問候語寫入後立即看到該問候語。不過,可寫入同一實體群組的頻率,限制在每秒只能寫入該實體群組一次。在設計實際要用的應用程式時,請牢記這點。請注意,使用 Memcache 這類服務,即可減少使用者在寫入資料後查詢整個實體群組時,看見過時結果的情況發生。

擷取提交的問候語

Cloud Datastore 有資料模型專用的精密查詢引擎。因為 Cloud Datastore 並非傳統的關聯資料庫,不是使用 SQL 來指定查詢,而是用下列其中一種方式來查詢資料:以 Datastore 查詢或是使用類似於 SQL 查詢語言的 GQL 進行查詢。如果要使用 Cloud Datastore 所有的查詢功能,建議透過 GQL 使用查詢。

MainPage 處理常式會擷取並顯示先前提交的問候語,而 greetings_query.fetch(10) 呼叫會執行查詢。

瞭解 Cloud Datastore 索引

Cloud Datastore 中的每個查詢,都是一個或多個「索引」的計算結果,索引是依順序排列的屬性值對應至實體金鑰的表格。因此,無論應用程式的資料儲存庫有多大,App Engine 都能快速提供結果。許多查詢可以透過內建的索引進行計算,但是 Cloud Datastore 需要「自訂索引」,才能執行更複雜的查詢。如果少了自訂索引,Cloud Datastore 就無法有效地執行查詢。

舉例來說,留言板應用程式會使用祖項查詢與排序順序,依留言板篩選並依日期排序。這項工作需要在應用程式的 index.yaml 檔案中指定自訂索引。您可以手動編輯這個檔案,或是在本機上執行應用程式查詢時自動編輯。在 index.yaml 中定義索引後,部署該應用程式時也會同時部署自訂索引的資訊。

index.yaml 中的查詢定義如下所示:

indexes:
- kind: Greeting
  ancestor: yes
  properties:
  - name: date
    direction: desc

如需 Cloud Datastore 索引的所有相關資訊,請參閱資料儲存庫索引頁面。如需瞭解 index.yaml 檔案的正確技術規格,請參閱 Python 資料儲存庫索引設定

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
App Engine standard environment for Python 2