您必須為實體建立模型類別。建立方式有以下兩種:
- 建立一個定義實體屬性的模型類別。
- 建立一個未事先定義實體的 Expando 模型類別。
本文件說明如何建立各種類型的模型類別,
同時亦說明如何建立模型掛鉤,讓您的應用程式可以在某些類型的作業之前或之後執行特定程式碼,例如每次執行 get()
之前。
建立包含屬性的模型類別
建立實體之前,您必須先建立一個定義一或多個實體屬性的模型類別。例如:
...
您可以為其中每個「帳戶」實體的使用者名稱、使用者 ID 和電子郵件地址指定屬性。
如要查看屬性類型的完整清單,請參閱實體屬性參考資料。
建立 Expando 模型類別
您不需要使用事先定義屬性的模型類別。
名為 Expando
的特殊模型子類別會變更其實體的行為,因此任何受指派的屬性都會儲存至資料儲存庫。請注意,這類屬性的開頭不得為底線。
以下說明如何建立 Expando 模型:
...
這樣寫入資料儲存庫的實體會含有 foo
屬性且整數值為 1
、bar
屬性且字串值為 'blah'
,以及重複的 tag
屬性且字串值為 'exp'
、'and'
和 'oh'
。
屬性會編入索引,您可以使用實體的 _properties
屬性進行檢查:
Expando
是透過從資料儲存庫取得值的方式建立,會包含儲存在資料儲存庫中所有屬性值的屬性。
應用程式可將預先定義的屬性新增至 Expando
子類別中:
...
這會讓 employee
含有值為 'Sandy'
的 name
屬性、值為 None
的 age
屬性、以及值為 'SF'
的動態屬性 location
。
如要建立不將屬性編入索引的 Expando
子類別,請在子類別定義中設定 _default_indexed = False
:
...
您也可以在 Expando
實體上設定 _default_indexed
。
在這種情況下,這會影響設定「之後」指派的所有屬性。
另一項實用技巧是查詢動態屬性的 Expando
種類。查詢如下所示
將無法運作,因為類別沒有位置屬性適用的屬性物件。反之,使用 GenericProperty
的話,Expando
類別可用於動態屬性:
使用模型掛鉤
NDB 提供簡易的掛鉤機制。定義掛鉤後,應用程式可以在某些類型的作業之前或之後執行特定程式碼,例如 Model
可能會在每次執行 get()
之前執行特定函式。
使用同步、非同步和適當方法的多個版本時,就會執行 hook 函式。舉例來說,「pre-get」掛鉤會套用到所有 get()
、get_async()
和 get_multi()
。每個掛鉤都有「RPC 前」和「RPC 後」的版本。
掛鉤機制在下列情況相當實用:
- 快取查詢
- 稽核每位使用者的 Cloud Datastore 活動
- 模擬資料庫觸發條件
以下範例顯示如何定義 hook 函式:
...
...
如果您將後置掛鉤與非同步 API 搭配使用,則掛鉤的觸發方式為呼叫 check_result()
、get_result()
或生成 (在 tasklet 中) 非同步方法的結果。後置掛鉤不會確認遠端程序呼叫 (RPC) 是否成功,即使失敗也會照樣執行。
所有後置掛鉤在呼叫簽章的結尾都有一個 Future 引數。這個 Future
物件會保留動作的結果。針對這個 Future
呼叫 get_result()
即可擷取結果;由於 Future
會在呼叫掛鉤之前完成,因此您可以確定 get_result()
不會遭到封鎖。
在執行前置掛鉤時引發例外狀況會造成無法提出要求。雖然掛鉤是在 <var>*</var>_async
方法中觸發,但您不可先佔遠端程序呼叫 (RPC) (藉由在 RPC 前置掛鉤中引發 tasklets.Return
)。