GqlQuery 類別

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

類別 GqlQuery 代表使用類似 SQL 的 App Engine 查詢語言 GQL,從 App Engine Datastore 擷取實體的查詢。如需 GQL 語法和功能的完整討論,請參閱 GQL 參考資料;另請參閱相關的 Query 類別,該類別會使用物件和方法 (而非 GQL) 來準備查詢。

GqlQuery 應在 google.appengine.ext.db 模組中定義。

附註:基於索引的查詢機制支援各種查詢,適用於大多數應用程式。不過,這種機制並不支援其他資料庫技術常見的某些查詢種類,Datastore 查詢引擎尤其不支援彙整與匯總查詢。如要瞭解 Datastore 查詢的限制,請參閱 Datastore 查詢頁面。

簡介

應用程式可以直接呼叫 GqlQuery 建構函式或實體種類模型類別的類別方法 gql(),藉此建立 GQL 查詢物件。GqlQuery 建構函式會將「查詢字串」當做引數,這個字串是開頭為 SELECT ... FROM model-name 的完整 GQL 陳述式。WHERE 子句中的值可為數字或字串常值,或可針對這些值使用參數繫結。參數可使用位置或關鍵字引數加以繫結:

q = GqlQuery("SELECT * FROM Song WHERE composer = 'Lennon, John'")

q = GqlQuery("SELECT __key__ FROM Song WHERE composer = :1", "Lennon, John")

q = GqlQuery("SELECT * FROM Song WHERE composer = :composer", composer="Lennon, John")

為方便起見,ModelExpando 類別都提供 gql() 類別方法,可傳回 GqlQuery 例項。這個方法需要 GQL 查詢字串,但無需 SELECT ... FROM model-name 前置字串,因為該字串會隱含在內:

q = Song.gql("WHERE composer = 'Lennon, John'")

接著,應用程式可透過下列方式執行查詢並存取結果:

  • 將查詢物件視為可疊代項目,一次處理一個相符實體:

    for song in q:
      print song.title

    這會間接呼叫查詢的 run() 方法來產生相符的實體,因此等同於:

    for song in q.run():
      print song.title

    您可以使用關鍵字引數 limit 設定要處理的結果數量上限:

    for song in q.run(limit=5):
      print song.title

    由於疊代器介面不會快取結果,所以從查詢物件建立新的疊代器會從頭重複相同的查詢。

  • 呼叫查詢的 get() 方法,取得在 Datastore 找到的第一個相符實體:

    song = q.get()
    print song.title
  • 呼叫查詢的 fetch() 方法,取得所有相符實體的清單,最多可包含指定數量的結果:

    results = q.fetch(limit=5)
    for song in results:
      print song.title

    run() 一樣,查詢物件不會快取結果,因此第二次呼叫 fetch() 會重新發出相同的查詢。

    注意:上述方法可以適用的情況不多;大多數情況下,使用 run() 會是比較好的選擇。

建構函式

GqlQuery 類別的建構函式定義如下:

class GqlQuery (query_string, *args, **kwds)

建立 GqlQuery 類別的例項,以便使用 GQL 查詢語言從 App Engine Datastore 擷取實體。

引數

query_string
包含完整 GQL 陳述式的字串。
args
位置參數值。
kwds
關鍵字參數值。

實例方法

GqlQuery 類別的例項有以下方法:

bind (*args, **kwds)

重新繫結查詢的參數值。重新繫結參數後,初次存取結果時會執行經過修改的查詢。

將參數重新繫結至現有的 GqlQuery 物件,比建構新的 GqlQuery 物件更快,因為系統不必再次剖析查詢字串。

引數

args
新的位置參數值。
kwds
新的關鍵字參數值。
projection ()

傳回投影或 None 中的屬性組合。

is_keys_only ()

傳回布林值,指示查詢是否為僅有金鑰的查詢。

run (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=None, batch_size=20, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

傳回可疊代物件以循環執行查詢結果。這可讓您用參數設定指定查詢作業,並反覆存取結果:

  1. 擷取並捨棄 offset 引數指定的結果數量。
  2. limit 引數限定的結果數量之內,擷取並傳回相符的結果。

迴圈的執行速度和 offset + limit 的總和呈現線性關係。如果您知道要擷取的結果數量,請一律設定明確的 limit 值。

這個方法採用非同步的預先擷取作業來提升效能。根據預設,這個方法會從 Datastore 分批擷取結果,讓應用程式得以停止疊代作業,避免擷取超過所需的結果。

提示:如果您要擷取所有可用結果卻無法確定數量,請將 batch_size 設為較大的值,例如 1000

提示:如果不需要變更預設的引數值,則可以直接使用查詢物件作為可疊代物件來控管循環。這會以預設引數隱含呼叫 run()

引數

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

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

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整以確定特定運算快速失敗 (例如更快速傳回回應給使用者、重試運算、嘗試不同運算,或新增運算至工作佇列)。
offset
傳回第一個結果之前略過的結果數。
limit
要傳回的結果數上限。 如果省略這個參數,則會使用在 GQL 查詢字串的 LIMIT 子句中指定的值。如果明確設為 None,則會擷取所有可用的結果。
batch_size
每批要嘗試擷取的結果數量。如果已設定 limit,則預設為指定的上限;否則預設為 20
keys_only
如為 true,則僅會傳回金鑰而非完整實體。相較於傳回完整實體的查詢,僅傳回金鑰的查詢可加快速度並節省成本。
projection
要傳回的屬性名稱清單或組合。系統僅會傳回擁有指定屬性的實體。如未指定,則預設會傳回完整實體。相較於傳回完整實體的查詢,投影查詢可加快速度並節省成本。

注意:指定這個參數可能會變更查詢的索引需求。

start_cursor
開始查詢的游標位置。
end_cursor
結束查詢的游標位置。
get (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

執行查詢並傳回第一個結果;如果找不到任何結果,則傳回 None。最多僅會從 Datastore 擷取一個結果;如有 GQL 查詢字串的 LIMIT 子句,則會予以忽略。

引數

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

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

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整以確定特定運算快速失敗 (例如更快速傳回回應給使用者、重試運算、嘗試不同運算,或新增運算至工作佇列)。
offset
傳回第一個結果之前略過的結果數。
keys_only
如為 true,則僅會傳回金鑰而非完整實體。相較於傳回完整實體的查詢,僅傳回金鑰的查詢可加快速度並節省成本。
projection
要傳回的屬性名稱清單或組合。系統僅會傳回擁有指定屬性的實體。如未指定,則預設會傳回完整實體。相較於傳回完整實體的查詢,投影查詢可加快速度並節省成本。

注意:指定這個參數可能會變更查詢的索引需求。

start_cursor
開始查詢的游標位置。
end_cursor
結束查詢的游標位置。
fetch (limit, read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

執行查詢並傳回 (可能空白的) 結果清單:

  1. 擷取並捨棄 offset 引數指定的結果數量。
  2. limit 引數限定的結果數量之內,擷取並傳回相符的結果。

這個方法的執行速度和 offset + limit 的總和呈現線性關係。

注意:這個方法只是 run() 方法的薄型包裝函式,相較於直接使用 run(),效率較低且耗用較多記憶體。您應該很少會需要用到 fetch(),我們提供這個方法的主要用意是方便您擷取記憶體內查詢結果的完整清單。

提示:fetch() 方法主要用於擷取 limit 引數所指定數量的結果。如要擷取所有可用查詢結果,但無法確定數量,請使用 run() 搭配較大的批次大小 (例如 run(batch_size=1000)),而非 fetch()

引數

limit
要傳回的結果數上限。 如果設為 None,系統會擷取所有可用的結果。
read_policy
指定所需資料一致性程度的讀取政策:
STRONG_CONSISTENCY
保證為最新結果,但僅限單一實體群組
EVENTUAL_CONSISTENCY
可涵蓋多個實體群組,但可能偶爾會傳回過時結果。一般來說,最終一致性查詢的執行速度,比同步一致性查詢更快,但並不保證絕對如此。

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

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整以確定特定運算快速失敗 (例如更快速傳回回應給使用者、重試運算、嘗試不同運算,或新增運算至工作佇列)。
offset
傳回第一個結果之前略過的結果數。
keys_only
如為 true,則僅會傳回金鑰而非完整實體。相較於傳回完整實體的查詢,僅傳回金鑰的查詢可加快速度並節省成本。
projection
要傳回的屬性名稱清單或組合。系統僅會傳回擁有指定屬性的實體。如未指定,則預設會傳回完整實體。相較於傳回完整實體的查詢,投影查詢可加快速度並節省成本。

注意:指定這個參數可能會變更查詢的索引需求。

start_cursor
開始查詢的游標位置。
end_cursor
結束查詢的游標位置。
count (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=1000, start_cursor=None, end_cursor=None)

傳回符合查詢的結果數。這比實際擷取所有結果的速度快上一個常數,但執行時間仍會以 offset + limit 的總和呈現線性關係。除非預期的結果數量不多,否則最好還是指定 limit 引數;否則這個方法會持續執行,直到計數完成或作業逾時為止。

引數

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

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

deadline
在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整以確定特定運算快速失敗 (例如更快速傳回回應給使用者、重試運算、嘗試不同運算,或新增運算至工作佇列)。
offset
略過的結果數,系統會在計算第一個結果之前略過這麼多個結果。
limit
要計算的結果數上限。

注意事項:如有明確指定,則這個參數會覆寫 GQL 查詢字串 LIMIT 子句中設定的任何值。不過,如果省略這個參數,預設值 1000「不會」覆寫 GQL 查詢的 LIMIT 子句,並且只會在沒有指定任何 LIMIT 子句時才會套用。

start_cursor
開始查詢的游標位置。
end_cursor
結束查詢的游標位置。
index_list ()

傳回已執行的查詢使用的索引清單,包括主要、複合、種類及單一屬性索引。

注意:如果您對尚未執行的查詢叫用這個方法,系統會產生 AssertionError 例外狀況。

注意:開發伺服器不完全支援這項功能。當與開發伺服器搭配使用時,結果將為空白的清單,或僅包含一個複合式索引的清單。

舉例來說,以下程式碼會列印查詢使用索引的各種資訊:

# other imports ...
import webapp2
from google.appengine.api import users
from google.appengine.ext import db

class Greeting(db.Model):
  author = db.StringProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):
  def get(self):
    user = users.get_current_user()
    q = db.GqlQuery(Greeting)
    q.filter("author =", user.user_id())
    q.order("-date")
    q.fetch(100)
    index_list = q.index_list()
    for ix in index_list:
      self.response.out.write("Kind: %s" % ix.kind())
      self.response.out.write("<br />")
      self.response.out.write("Has ancestor? %s" % ix.has_ancestor())
      self.response.out.write("<br />")
      for name, direction in ix.properties():
        self.response.out.write("Property name: "+name)
        self.response.out.write("<br />")
        if direction == db.Index.DESCENDING:
          self.response.out.write("Sort direction: DESCENDING")
        else:
          self.response.out.write("Sort direction: ASCENDING")
        self.response.out.write("<br />")

這會針對各個索引產生類似以下內容的輸出:

Kind: Greeting
Has ancestor? False
Property name: author
Sort direction: ASCENDING
Property name: date
Sort direction: DESCENDING
cursor ()

傳回 base64 編碼的「游標字串」,表示在查詢結果集之中,上次擷取結果之後的位置。游標字串可安全用於 HTTP GETPOST 參數,也可儲存於 Datastore 或 Memcache 中。您日後叫用相同的查詢時,可以透過 start_cursor 參數或 with_cursor() 方法提供這個字串,以便繼續從這個位置擷取結果。

注意:如果您對尚未執行的查詢叫用這個方法,系統會產生 AssertionError 例外狀況。

注意:並非所有查詢都與游標相容,詳情請參閱「Datastore 查詢」頁面。

with_cursor (start_cursor, end_cursor=None)

在查詢的結果集中,指定要從中擷取結果的起始與 (選用) 結束位置。先叫用查詢再呼叫 cursor() 即可取得代表起始與結束位置的游標字串。目前的查詢必須與先前叫用的查詢相同,包括實體種類、屬性篩選器、祖系篩選器及排序順序。

引數

start_cursor
Base64 編碼的游標字串,指定查詢的起始位置。
end_cursor
Base64 編碼的游標字串,指定查詢的結束位置。