建立及使用實體金鑰

每個實體都是以金鑰加以識別;這些金鑰在應用程式的 Cloud Datastore 執行個體中具有唯一性,並包含下列項目:

  • 種類:通常是實體所屬的模型類別名稱,但您可以覆寫 classmethod _get_kind(),將這個名稱變更為其他字串。
  • 識別碼:您可以指定自訂的「金鑰名稱」作為識別碼,或由 Cloud Datastore 自動產生整數 ID。

指定自訂金鑰名稱

以下範例使用命名參數 id 以字串識別碼間接建立金鑰:

account = Account(
    username='Sandy', userid=1234, email='sandy@example.com',
    id='sandy@example.com')

return account.key.id()  # returns 'sandy@example.com'

您也可以直接設定金鑰名稱:

account.key = ndb.Key('Account', 'sandy@example.com')

# You can also use the model class object itself, rather than its name,
# to specify the entity's kind:
account.key = ndb.Key(Account, 'sandy@example.com')

由 Cloud Datastore 產生用於金鑰的 ID

以下程式碼顯示如何使用自動產生的 ID 作為金鑰:

# note: no id kwarg
account = Account(username='Sandy', userid=1234, email='sandy@example.com')
account.put()
# account.key will now have a key of the form: ndb.Key(Account, 71321839)
# where the value 71321839 was generated by Datastore for us.

在金鑰中使用祖系路徑

從根實體開始,再從父項到子項,最後到指定實體的實體序列,構成該實體的「祖系路徑」。實體、實體的父項、父項的父項,以及以此類推下去的父項,為實體的「祖系」。Cloud Datastore 中的實體會形成與檔案系統的階層目錄結構類似的階層金鑰體系。

用於識別實體的完整金鑰,其中包含一系列指定其祖系路徑的種類-識別碼組合,並會以實體本身的種類-識別碼組合作結。Key 類別的建構函式方法在接受這類一系列的種類-識別碼組合後,會傳回代表對應實體金鑰的物件。

以下範例顯示儲存各個修訂版本訊息的部落格服務。訊息排列於帳戶下方,且修訂版本排列於訊息下方。

class Revision(ndb.Model):
    message_text = ndb.StringProperty()
...
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '2')
ndb.Key('Account', 'larry@example.com', 'Message', 456, 'Revision', '1')
ndb.Key('Account', 'larry@example.com', 'Message', 789, 'Revision', '2')

範例中的 ('Account', 'sandy@example.com')('Message', 123)('Revision', '1') 都是種類-識別碼組合的例子。

請注意,Message 並非模型類別,只能用來集合修訂,無法儲存資料。

如程式碼範例所示,實體的種類是由清單中的「最後一個」種類/名稱組合指定:ndb.Key('Revision', '1')

使用命名參數

您可以使用命名參數 parent 直接指定祖系路徑中的任何實體。以下所有標記法均代表相同金鑰:

ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')

ndb.Key('Revision', '1', parent=ndb.Key(
    'Account', 'sandy@example.com', 'Message', 123))

ndb.Key('Revision', '1', parent=ndb.Key(
    'Message', 123, parent=ndb.Key('Account', 'sandy@example.com')))

指定根實體

根實體的祖系路徑空白,並且金鑰僅包含實體本身的種類與識別碼。

sandy_key = ndb.Key(Account, 'sandy@example.com')

指定包含祖系的實體

如要以父項金鑰插入新訊息:

account_key = ndb.Key(Account, 'sandy@example.com')

# Ask Datastore to allocate an ID.
new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]

# Datastore returns us an integer ID that we can use to create the message
# key
message_key = ndb.Key('Message', new_id, parent=account_key)

# Now we can put the message into Datastore
initial_revision = Revision(
    message_text='Hello', id='1', parent=message_key)
initial_revision.put()

如果金鑰使用父項建立,parent() 方法會傳回代表父系實體的金鑰:

message_key = initial_revision.key.parent()

使用數字金鑰 ID

您可以建立實體而不用指定 ID,由資料儲存庫自動產生數字 ID。如果您選擇指定部分 ID,並且讓 Cloud Datastore 自動產生其他 ID,您可能會違反唯一金鑰的規定。為避免發生此情形,請保留特定範圍的數字來選擇 ID,或使用字串 ID 以便徹底杜絕此問題。

如要保留特定範圍的 ID,請使用模型類別的 allocate_ids() 類別方法進行下列操作:

  • 分配指定數量的 ID
  • 分配指定最大值以下的所有 ID。

分配 ID

如要分配 100 個 ID 給指定模型類別 MyModel

first, last = MyModel.allocate_ids(100)

如要分配 100 個 ID 給父項金鑰為 p 的實體:

first, last = MyModel.allocate_ids(100, parent=p)

傳回的 firstlast 值為分配的第一個和最後一個 ID。您可以使用這些 ID 建構金鑰,如下所示:

keys = [ndb.Key(MyModel, id) for id in range(first, last+1)]

這些金鑰先前並未由資料儲存庫的內部 ID 產生器傳回,日後也不會在呼叫內部 ID 產生器時傳回。不過 allocate_ids() 方法僅會與 ID 產生器互動,而不會檢查傳回的 ID 是否已存在於資料儲存庫中。

如要分配指定最大值以下的所有 ID:

first, last = MyModel.allocate_ids(max=N)

這可確保小於或等於 N 的所有 ID 都會視為已分配。傳回的 firstlast 值代表此作業保留的 ID 範圍。嘗試保留已分配的 ID 並不構成錯誤;如果發生此情形,first 代表尚未分配的第一個 ID,而 last 則是最後一個分配的 ID。

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

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

這個網頁
Python 2 適用的 App Engine 標準環境