Datastore 函式

附註:我們強烈建議建構新應用程式的開發人員使用 NDB 用戶端程式庫,因為 NDB 用戶端程式庫與本用戶端程式庫相較之下有幾個優點,例如能透過 Memcache API 自動將實體加入快取。如果您目前使用的是舊版的 DB 用戶端程式庫,請參閱從 DB 至 NDB 的遷移指南

本頁所述函式是在 google.appengine.ext.db 套件中定義。

函式

allocate_ids (model, count)

在 Datastore 中,為 Datastore 種類和父項組合分配一批 ID。

Datastore 的自動 ID 序列產生器不會使用以這種方式分配的 ID,且可在實體鍵中使用而不發生衝突。

引數

model
要分配 ID 批次的模型鍵。這是一般,但只需使用鍵的父項和類型,即可決定要使用的 ID 序列。
count
要分配的 ID 數量。

傳回所配置第一個和最後一個 ID 的組合。例如,如果您使用這個函式分配 10 個 ID,就會獲得格式為 (1, 10) 的傳回值,而非所建立 ID 的完整清單。

配置和使用 ID 的範例如下:

# allocate for MyModel without an instance
handmade_key = db.Key.from_path('MyModel', 1)
first_batch = db.allocate_ids(handmade_key, 10)
first_range = range(first_batch[0], first_batch[1] + 1)

# or allocate using an existing key
model_instance = MyModel.all().get()
second_batch = db.allocate_ids(model_instance.key(), 10)
second_range = range(second_batch[0], second_batch[1] + 1)

# and then use them! woo!
my_id = second_range.pop(0)
new_key = db.Key.from_path('MyModel', my_id)
new_instance = MyModel(key=new_key)
new_instance.put()
assert new_instance.key().id() == my_id

# the Datastore will not assign ids in first_batch or second_batch
another_instance = MyModel()
another_instance.put()
assert another_instance.key().id() not in first_range
assert another_instance.key().id() not in second_range
allocate_ids_async (model, count)

在 Datastore 中,以非同步方式為 Datastore 種類和父項組合分配一批 ID。

這個函式與 allocate_ids() 幾乎相同,唯一的差異在於這個函式會傳回非同步物件。您可以對傳回值呼叫 get_result(),以便封鎖呼叫並傳回結果。

引數

model
db.Model 例項、金鑰或字串,可用來當做指定 ID 分配序列的範本。傳回的 ID 只能用於與這組金鑰擁有相同父項 (如有) 和種類的實體。
count
要分配的 ID 數量。

傳回所配置第一個和最後一個 ID 的組合。例如,如果您使用這個函式分配 10 個 ID,就會獲得格式為 (1, 10) 的傳回值,而非所建立 ID 的完整清單。

allocate_id_range (model, start, end, **kwargs)

分配特定起迄點範圍內的 ID。這些 ID 分配好之後,即可透過手動方式指派給新建立的實體。

Datastore 的自動 ID 分配器不會指派已分配的金鑰 (無論是透過自動 ID 分配或明確呼叫 'allocate_ids')。因此,寫入指定金鑰範圍的實體便永遠不會遭到覆寫。然而,根據傳回的金鑰範圍狀態,如果將這個範圍內的金鑰手動指派給實體,則寫入這些實體時可能會覆寫現有的實體 (或是由個別要求寫入的新實體)。

只有在您有要保留的現有數字 ID 範圍時 (例如,大量載入已具有 ID 的實體),才使用此函式。如果您不在意收到的 ID,請改為使用 allocate_ids()

引數

model
db.Model 例項、金鑰或字串,可用來當做指定 ID 分配序列的範本。傳回的 ID 只能用於與這組金鑰擁有相同父項 (如有) 和種類的實體。
start
要分配的第一個 ID,為數字。
end
要分配的最後一個 ID,為數字。

傳回 (KEY_RANGE_EMPTYKEY_RANGE_CONTENTIONKEY_RANGE_COLLISION) 其中一個。如果不是 KEY_RANGE_EMPTY,表示使用已指派的鍵範圍可能發生問題。

create_transaction_options (**kwargs)

建立交易選項物件 (類別 TransactionOptions),用於控制交易執行作業。您會將產生的物件當做第一個引數傳送至 run_in_transaction_options() 函式。

引數

傳播
如果此交易函式是在其他交易中呼叫,該怎麼辦?
允許
如果已進行交易,請繼續使用;如果尚未進行交易,請開始交易。

附註:如果使用此政策的函式擲回例外狀況,擷取例外狀況並修訂外部交易可能並不安全;該函式可能會讓外部交易呈現不良狀態。

必填
如果交易正在進行,則繼續執行。如果未進行交易,則傳回 BadRequestError 例外狀況。

附註:如果使用此政策的函式擲回例外狀況,擷取例外狀況並修訂外部交易可能並不安全;該函式可能會讓外部交易呈現不良狀態。

獨立
建立新的交易,並暫停所有現有交易。

附註:使用此政策的函式不應傳回在新交易中讀取到的任何實體,因為實體在交易方面與外部交易並不一致。

NESTED
(尚未支援) 在現有交易中建立巢狀交易。
xg
如果為 True,則允許 跨群組 (XG) 交易。如果設為非布林值,則會傳送 BadArgumentError 例外狀況。
重試
在交易提交失敗時,嘗試重試的次數。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

以下範例會建立後續跨群組 (XG) 交易的選項:

from google.appengine.ext import db

xg_on = db.create_transaction_options(xg=True)

def my_txn():
  x = MyModel(a=3)
  x.put()
  y = MyModel(a=7)
  y.put()

db.run_in_transaction_options(xg_on, my_txn)
delete (models, deadline=60)

從 Datastore 刪除一或多個模型執行個體。

引數

模型
模型例項、實體索引鍵,或要刪除的模型例項或實體索引鍵清單 (或其他可枚舉項目)。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

put() 一樣,如果提供多個鍵,這些鍵可能會屬於多個實體群組

如果作業期間發生任何錯誤,即便系統已確實刪除部分實體,仍一律會傳回例外狀況。如果呼叫傳回時沒有傳回例外狀況,則所有實體均已成功刪除。

注意:如果您在單一作業中刪除多個實體,我們並不保證會一次刪除所有實體,除非該項作業是在交易中執行。即使查詢採用強一致性,其他查詢 Datastore 的程序可能會看到不一致的結果。

delete_async (models, deadline=60)

以非同步方式從 Datastore 刪除一或多個模型執行個體。

這個函式與 delete() 幾乎相同,唯一的差異在於這個函式會傳回非同步物件。您可以對傳回值呼叫 get_result(),以便封鎖呼叫。

引數

模型
模型例項、實體索引鍵,或要刪除的模型例項或實體索引鍵清單 (或其他可枚舉項目)。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

put() 一樣,如果提供多個鍵,這些鍵可能會屬於多個實體群組

這個函式傳回的物件可讓您封鎖呼叫結果。

如果作業期間發生任何錯誤,即便系統已確實刪除部分實體,仍一律會傳回例外狀況。如果呼叫傳回時沒有傳回例外狀況,則所有實體均已成功刪除。

注意:如果您在單一作業中刪除多個實體,我們並不保證會一次刪除所有實體,除非該項作業是在交易中執行。即使查詢是採用強一致性執行,其他查詢 Datastore 的程序可能會看到不一致的結果。

get (keys, read_policy=STRONG_CONSISTENCY, deadline=60)

從 Datastore 使用指定的金鑰擷取特定模型執行個體。

引數

keys
要擷取的實體金鑰、金鑰的字串表示法,或是金鑰或金鑰字串表示法的清單。
read_policy
指定所需資料一致性程度的讀取政策:
STRONG_CONSISTENCY
保證為最新結果,但僅限單一實體群組
EVENTUAL_CONSISTENCY
可涵蓋多個實體群組,但可能偶爾會傳回過時結果。一般來說,最終一致性查詢的執行速度,比同步一致性查詢更快,但並不保證絕對如此。

注意:全域 (非祖系) 查詢會忽略這個引數。

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

如果 keys 包含單一金鑰 (或其字串表示法),這個函式會在該金鑰存在於 Datastore 時傳回與金鑰相關的模型執行個體,否則會傳回 None。如果 keys 為清單,傳回值為對應的模型執行個體清單,如果指定金鑰沒有實體,則為 None 值。

另請參閱 Model.get()

get_async (keys, read_policy=STRONG_CONSISTENCY, deadline=60)

以非同步方式從 Datastore 中擷取特定的模型執行個體。

這個函式與 get() 幾乎相同,唯一的差異在於這個函式會傳回非同步物件。您可以對傳回值呼叫 get_result(),以便封鎖呼叫並傳回結果。

引數

keys
要擷取的實體金鑰、金鑰的字串表示法,或是金鑰或金鑰字串表示法的清單。
read_policy
指定所需資料一致性程度的讀取政策:
STRONG_CONSISTENCY
保證為最新結果,但僅限單一實體群組
EVENTUAL_CONSISTENCY
可涵蓋多個實體群組,但可能偶爾會傳回過時結果。一般來說,最終一致性查詢的執行速度,比同步一致性查詢更快,但並不保證絕對如此。

注意:全域 (非祖系) 查詢會忽略這個引數。

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

如果 keys 包含單一金鑰 (或其字串表示法),這個函式會在該金鑰存在於 Datastore 時傳回與金鑰相關的模型執行個體,否則會傳回 None。如果 keys 為清單,傳回值為對應的模型執行個體清單,如果指定金鑰沒有實體,則為 None 值。

另請參閱 Model.get()

get_indexes ()

傳回屬於呼叫應用程式的複合索引清單。

以下範例說明如何取得和使用索引:

def get_index_state_as_string(index_state):
  return {db.Index.BUILDING:'BUILDING', db.Index.SERVING:'SERVING',
          db.Index.DELETING:'DELETING', db.Index.ERROR:'ERROR'}[index_state]

def get_sort_direction_as_string(sort_direction):
  return {db.Index.ASCENDING:'ASCENDING',
          db.Index.DESCENDING:'DESCENDING'}[sort_direction]


def dump_indexes():
  for index, state in db.get_indexes():
    print "Kind: %s" % index.kind()
    print "State: %s" % get_index_state_as_string(state)
    print "Is ancestor: %s" % index.has_ancestor()
    for property_name, sort_direction in index.properties():
      print "  %s:%s" % (property_name,
                         get_sort_direction_as_string(sort_direction))
get_indexes_async ()

以非同步方式傳回屬於呼叫應用程式的複合索引清單。

is_in_transaction ()

傳回布林值,表示交易是否正在執行目前的範圍。

model_to_protobuf (model_instance)

建立 Model 例項的通訊協定緩衝區序列化資料。通訊協定緩衝區是 Google 的序列化格式,用於遠端程序呼叫,且對於備份及還原目的的 Datastore 物件序列化十分有用。

注意事項:相較於 開放原始碼的通訊協定緩衝區格式,這個函式會為通訊協定緩衝區使用不同 (舊版) 的格式,而且這個格式與開放原始碼部署項目不相容。

引數

model_instance
要序列化的類別 Model (或子類別) 的例項。

以位元組字串格式,傳回通訊協定緩衝區序列化的物件。

model_from_protobuf (pb)

依據通訊協定緩衝區序列化結果建立 Model 例項,詳情請參閱 model_to_protobuf()

引數

pb
model_to_protobuf() 傳回的通訊協定緩衝區序列化結果。

傳回適當種類類別的物件。如果種類類別不存在,系統會傳回 KindError 例外狀況。如果該物件對模型無效,則系統會傳回 BadValueError 例外狀況。

您可以與其他 Model 例項一樣,將新物件儲存至 Datastore,例如呼叫其 put() 方法。該物件會保留建立通訊協定緩衝區時擁有的金鑰。若 Datastore 中已有具備該金鑰的物件,則儲存去序列化的物件會覆寫既有物件。

注意:如果物件的金鑰使用系統指派的 ID,且該 ID 尚未分配給指定的路徑和種類,便會成功儲存,但不會保存 ID。未來建立的物件可能會分配到該 ID,且會覆寫先前的物件。為確保安全,請只在物件序列化時所在的應用程式中還原物件。

model_is_projection (model_instance)

如果指定的查詢 (model_instance) 是投影查詢 (而非完整實體查詢),則系統會傳回 True

引數

model_instance
您要檢查的查詢,以判斷該查詢是否為投影查詢。

如果查詢是投影查詢,則會傳回 True;如果不是,則會傳回 False

put (models, deadline=60)

將一個或多個模型執行個體寫入 Datastore。

引數

模型
要儲存的模型執行個體或模型執行個體清單。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

如果提供多個模型實例,這些模型實例可能會出現在多個實體群組中。

操作過程中如發生任何錯誤,即便實際上已刪除部分實體,仍會一律傳回例外狀況。如果呼叫傳回時沒有傳回例外狀況,則所有實體均已成功寫入。

如果 models 含有單一模型項目,這個函式會傳回相對應的 Key 物件。如果 models 是清單,傳回值就會是相對應的 Key 物件清單。

注意:如果您在單一作業中寫入多個實體,我們並不保證會一次寫入所有實體,除非該項作業是在交易中執行。即使查詢採用強一致性,其他查詢 Datastore 的程序可能會看到不一致的結果。

put_async (models, deadline=60)

將一個或多個模型執行個體寫入 Datastore。

這個函式與 put() 幾乎相同,唯一的差異在於這個函式會傳回非同步物件。您可以對傳回值呼叫 get_result(),以便封鎖呼叫並傳回結果。

引數

模型
要儲存的模型執行個體或模型執行個體清單。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。

如果提供多個模型實例,這些模型實例可能會出現在多個實體群組中。

操作過程中如發生任何錯誤,即便實際上已刪除部分實體,仍會一律傳回例外狀況。如果呼叫傳回時沒有傳回例外狀況,則所有實體均已成功寫入。

這個函式會傳回非同步物件,該物件可用於呼叫 get_result()。傳回的結果與 put() 相同。

注意:如果您在單一作業中寫入多個實體,我們並不保證會一次寫入所有實體,除非該項作業是在交易中執行。即使查詢採用強一致性,其他查詢 Datastore 的程序可能會看到不一致的結果。

query_descendants (model_instance)

傳回針對某個模型實例所有下階進行的查詢。

引數

model_instance
您要尋找其子項的模型執行個體。
run_in_transaction (function, *args, **kwargs)

在單一交易中執行含有 Datastore 更新的函式。如果任何程式碼在交易期間引發例外狀況,系統會回復在交易中所做的所有更新。或者,您也可以使用 @db.transactional() 修飾符。

引數

function
要執行的函式。
args
要傳遞至函式的位址引數。
kwargs
要傳遞至函式的關鍵字引數。

如果函式傳回值,run_in_transaction() 會將值傳回給呼叫端。

如果函式傳回例外狀況,便會復原交易。如果例外狀況是 Rollback,系統就不會重新傳回。如為其他例外狀況,則會重新傳回至呼叫者。

針對交易,Datastore 使用樂觀鎖定和重試。如果函式準備的交易無法提交,run_in_transaction() 會再次呼叫該函式,最多重試 3 次交易。(如要使用不同的重試次數,請使用 run_in_transaction_custom_retries()。) 由於交易函式可能會為單一交易呼叫多次,因此函式不應有副作用,包括修改引數。

如果無法修訂交易 (例如因為高爭用率),系統會傳回 TransactionFailedError 例外狀況。

from google.appengine.ext import db

class Counter(db.Model):
  name = db.StringProperty()
  count = db.IntegerProperty(default=0)

def decrement(key, amount=1):
  counter = db.get(key)
  counter.count -= amount
  if counter.count < 0:        # Don't let counter go negative
    raise db.Rollback()
  db.put(counter)

q = db.GqlQuery("SELECT * FROM Counter WHERE name = :1", "foo")
counter = q.get()
db.run_in_transaction(decrement, counter.key(), amount=5)
run_in_transaction_custom_retries (retries, function, *args, **kwargs)

在單一交易中執行含有 Datastore 更新的函式,並在爭用發生時依指定次數來重試交易。如果任何程式碼在交易期間傳回例外狀況,便會復原交易期間的所有更新。

除了能夠指定重試次數之外,這個函式的行為與 run_in_transaction() 相同。

引數

重試
在實體群組內發生爭用情形 (有多位使用者同時嘗試修改群組) 時,呼叫此函式的最大次數。
function
要執行的函式。
args
要傳遞至函式的位址引數。
kwargs
要傳遞至函式的關鍵字引數。
run_in_transaction_options (options, function, *args, **kwargs)

使用 交易選項物件中指定的選項,在單一交易中執行包含 Datastore 更新的函式。如果任何程式碼在交易期間引發例外狀況,系統就會回復在交易中所做的所有 Datastore 更新。

如為 跨群組 (XG) 交易,交易選項物件中的 xg 參數必須設為 True

引數

選項
交易選項物件,其中包含此交易使用的設定。如要啟用 XG 交易,其 xg 參數必須設為 True
function
要執行的函式。
args
要傳遞至函式的位址引數。
kwargs
要傳遞至函式的關鍵字引數。

如果函式傳回值,run_in_transaction_options() 會將值傳回給呼叫端。

如果函式傳回例外狀況,便會復原交易。如果例外狀況是 Rollback,系統就不會重新傳回。如為其他例外狀況,則會重新傳回至呼叫者。

針對交易,Datastore 使用樂觀鎖定和重試。如果函式準備的交易無法提交,run_in_transaction_options() 會再次呼叫函式,重試交易,直到重試次數達到交易選項物件中指定的重試次數為止。單一交易可多次呼叫交易函式,因此該函式不應有副作用,包括修改引數。

如果無法修訂交易 (例如因為高爭用率),系統會傳回 TransactionFailedError 例外狀況。

以下範例顯示如何使用此函式執行跨群組交易

from google.appengine.ext import db

xg_options = db.create_transaction_options(xg=True)

def my_txn():
  x = MyModel(a=3)
  x.put()
  y = MyModel(a=7)
  y.put()

db.run_in_transaction_options(xg_options, my_txn)
to_dict (model_instance, dictionary=None)

建立並傳回模型執行個體的字典表示法。

引數

model_instance
要複製的模型例項。
字典
如果存在,則為要合併模型資料的字典。模型值覆寫字典中的值;並保留與模型執行個體欄位不對應的字典項目。

修飾符

@db.transactional (propagation=ALLOWED, xg=False, retries=3, deadline=60)

讓函式在 db 交易中執行。因此,您可以呼叫 func(),而非 run_in_transaction(func)

引數

傳播
如果此交易函式是在其他交易中呼叫,該怎麼辦?
允許
如果已進行交易,請繼續使用;如果尚未進行交易,請開始交易。

附註:如果使用此政策的函式擲回例外狀況,擷取例外狀況並修訂外部交易可能並不安全;該函式可能會讓外部交易呈現不良狀態。

必填
如果交易正在進行,則繼續執行。如果未進行交易,則傳回 BadRequestError 例外狀況。

附註:如果使用此政策的函式擲回例外狀況,擷取例外狀況並修訂外部交易可能並不安全;該函式可能會讓外部交易呈現不良狀態。

獨立
建立新的交易,並暫停所有現有交易。

附註:使用此政策的函式不應傳回在新交易中讀取到的任何實體,因為實體在交易方面與外部交易並不一致。

NESTED
(尚未支援) 在現有交易中建立巢狀交易。
xg
如果為 True,則允許 跨群組 (XG) 交易。如果設為非布林值,則會傳送 BadArgumentError 例外狀況。
重試
在交易提交失敗時,嘗試重試的次數。
deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整來確保特定作業快速失敗 (例如更快將回應傳回給使用者、重試作業、嘗試不同作業,或是將作業新增至工作佇列)。
@db.non_transactional (allow_existing=True)

確保函式在 db 交易外執行,即使從交易中呼叫也一樣。

引數

allow_existing
如果為 True,則允許從現有交易中呼叫函式;如果為 False,則改為擲回 BadRequestError 例外狀況。