附註:我們強烈建議建構新應用程式的開發人員使用 NDB 用戶端程式庫,因為 NDB 用戶端程式庫與本用戶端程式庫相較之下有幾個優點,例如能透過 Memcache API 自動將實體加入快取。如果您目前使用的是舊版的 DB 用戶端程式庫,請參閱從 DB 至 NDB 的遷移指南。
類別 Query
代表從 App Engine Datastore 擷取實體的查詢。(另請參閱相關的 GqlQuery
類別,這個類別使用類似 SQL 的 GQL 查詢語言來定義查詢)。
Query
應在 google.appengine.ext.db
模組中定義。
附註:基於索引的查詢機制支援各種查詢,適用於大多數應用程式。不過,這種機制並不支援其他資料庫技術常見的某些查詢種類,Datastore 查詢引擎尤其不支援彙整與匯總查詢。如要瞭解 Datastore 查詢的限制,請參閱 Datastore 查詢頁面。
簡介
應用程式可以直接呼叫 Query
建構函式,為指定實體種類建立查詢物件
class Song(db.Model): title = db.StringProperty() composer = db.StringProperty() date = db.DateTimeProperty() q = db.Query(Song)
或是呼叫該種類模型類別的 all()
類別方法:
q = Song.all()
在未經進一步修改的情況下,類別 Query
的產生例項會擷取指定類型的所有現有實體。您可以使用物件的 method 呼叫,藉此新增更多篩選條件、祖系條件和排序順序,自訂查詢:
q.filter('title =', 'Imagine') q.ancestor(ancestor_key) q.order('-date')
為求方便起見,所有這些方法都會傳回查詢物件本身,以在單一陳述式中串聯:
q.filter('title =', 'Imagine').ancestor(key).order('-date')
接著,應用程式可透過下列方式執行查詢並存取結果:
-
將查詢物件視為可疊代項目,一次處理一個相符實體:
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()
會是比較好的選擇。
建構函式
Query
類別的建構函式定義如下:
- class Query (model_class=None, keys_only=False, cursor=None, namespace=None, projection=None, distinct=False)
-
建立
Query
類別的例項,用於從 App Engine Datastore 擷取實體。在未經進一步修改的情況下,產生的查詢物件會擷取
model_class
指定種類的所有現有實體。此時,您可以使用例項方法filter()
、ancestor(),
和order()
來自訂查詢,藉此新增更多篩選條件、祖系條件和排序順序。引數
- model_class
- Model (或 Expando) 類別,代表查詢適用的實體類型。
- keys_only
- 如為
true
,則僅會傳回金鑰而非完整實體。相較於傳回完整實體的查詢,僅傳回金鑰的查詢可加快速度並節省成本。 - cursor
- 要繼續查詢的游標位置。
- namespace
- 要用於查詢的命名空間。
- projection
- 要傳回的屬性名稱清單或組合。系統僅會傳回擁有指定屬性的實體。如未指定,則預設會傳回完整實體。相較於傳回完整實體的查詢,投影查詢可加快速度並節省成本。
注意:指定這個參數可能會變更查詢的索引需求。
- distinct
- 以投影查詢來說,distinct=True 指定了只有完全不重複的結果會透過結果傳回。如有多個實體的投影屬性包含相同的值,這種方式只會傳回第一個結果。
- True
- 只傳回投影中屬性每個不重複值組合的第一個結果。
- 錯誤
- 會傳回所有結果。
實例方法
Query
類別的例項有以下方法:
- filter (property_operator, value)
-
在查詢中加入屬性篩選器。查詢僅會傳回屬性符合所有篩選器的實體。
引數
- property_operator
- 字串中包含屬性名稱和選用的比較運算子 (
=
、!=
、<
、<=
、>
、>=
、IN
),以空格分隔:例如'age
>'
。如果只指定屬性名稱,而未指定比較運算子,則篩選器會預設比較相等性 (=
)。 - value
- 要與屬性值比較的值。例如:
q.filter('height >', 42).filter('city =', 'Seattle') q.filter('user =', users.get_current_user())
指定的比較值應跟要比較的屬性具有相同的值類型。
- ancestor (ancestor)
-
在查詢中加入祖系篩選器。查詢僅會傳回具有指定祖系的實體。
引數
- ancestor
- 祖系實體或索引鍵。
- order (property)
-
在查詢中加入排序順序。如果加入的排序順序不只一個,則會依照指定順序套用。
引數
- property
- 字串,提供要排序的屬性名稱,可選擇在前面加上連字號 (
-
) 來指定遞減順序。省略連字號會預設為遞增順序。例如:# Order alphabetically by last name: q.order('last_name') # Order by height, tallest to shortest: q.order('-height')
- 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)
-
傳回可疊代物件以循環執行查詢結果。這可讓您用參數設定指定查詢作業,並反覆存取結果:
- 擷取並捨棄
offset
引數指定的結果數量。 - 在
limit
引數限定的結果數量之內,擷取並傳回相符的結果。
迴圈的執行速度和
offset
+limit
的總和呈現線性關係。如果您知道要擷取的結果數量,請一律設定明確的limit
值。這個方法採用非同步的預先擷取作業來提升效能。根據預設,這個方法會從 Datastore 分批擷取結果,讓應用程式得以停止疊代作業,避免擷取超過所需的結果。
提示:如果您要擷取所有可用結果卻無法確定數量,請將
batch_size
設為較大的值,例如1000
。提示:如果不需要變更預設的引數值,則可以直接使用查詢物件作為可疊代物件來控管循環。這會以預設引數隱含呼叫
run()
。引數
- read_policy
- 指定所需資料一致性程度的讀取政策:
- STRONG_CONSISTENCY
- 保證為最新結果,但僅限單一實體群組。
- EVENTUAL_CONSISTENCY
- 可涵蓋多個實體群組,但可能偶爾會傳回過時結果。一般來說,最終一致性查詢的執行速度,比同步一致性查詢更快,但並不保證絕對如此。
注意:全域 (非祖系) 查詢會忽略這個引數。
- deadline
- 在因錯誤而取消之前,等待 Datastore 傳回結果的秒數上限,可接受整數或浮點值。不得高於預設值 (60 秒),但可向下調整以確定特定運算快速失敗 (例如更快速傳回回應給使用者、重試運算、嘗試不同運算,或新增運算至工作佇列)。
- offset
- 傳回第一個結果之前略過的結果數。
- 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
。引數
- 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)
-
執行查詢並傳回 (可能空白的) 結果清單:
- 擷取並捨棄
offset
引數指定的結果數量。 - 在
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
,則僅會傳回金鑰而非完整實體。相較於傳回完整實體的查詢,僅傳回金鑰的查詢可加快速度並節省成本。 - 投影
- 要傳回的屬性名稱清單或組合。系統僅會傳回擁有指定屬性的實體。如未指定,則預設會傳回完整實體。相較於傳回完整實體的查詢,投影查詢可加快速度並節省成本。
注意:指定這個參數可能會變更查詢的索引需求。
- 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
- 要計算的結果數上限。
- 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.Query(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
GET
與POST
參數,也可儲存於 Datastore 或 Memcache 中。您日後叫用相同的查詢時,可以透過start_cursor
參數或with_cursor()
方法提供這個字串,以便繼續從這個位置擷取結果。注意:如果您對尚未執行的查詢叫用這個方法,系統會產生
AssertionError
例外狀況。注意:並非所有查詢都與游標相容,詳情請參閱「Datastore 查詢」頁面。
- with_cursor (start_cursor, end_cursor=None)
-
在查詢的結果集中,指定要從中擷取結果的起始與 (選用) 結束位置。先叫用查詢再呼叫
cursor()
即可取得代表起始與結束位置的游標字串。目前的查詢必須與先前叫用的查詢相同,包括實體種類、屬性篩選器、祖系篩選器及排序順序。引數
- start_cursor
- Base64 編碼的游標字串,指定查詢的起始位置。
- end_cursor
- Base64 編碼的游標字串,指定查詢的結束位置。