查詢類別

注意事項:強烈建議建構新應用程式的開發人員使用 NDB 用戶端程式庫。相較於這個用戶端程式庫,NDB 用戶端程式庫具備幾項優勢,例如能夠透過 Memcache API 自動快取實體。如果您目前使用的是舊版 DB 用戶端程式庫,請參閱從 DB 遷移至 NDB 用戶端程式庫的操作指南。

Query 類別代表的是從 App Engine Datastore 擷取實體的查詢 (另請參閱相關的 GqlQuery 類別,這個類別使用類似 SQL 的 GQL 查詢語言來定義查詢)。

Query 是在 google.appengine.ext.db 模組中定義。

注意:以索引為基礎的查詢機制支援各種查詢,適用於大多數應用程式。不過這種機制並不支援其他資料庫技術常見的某些查詢種類,Cloud Datastore 查詢引擎尤其不支援彙整與匯總查詢。如要瞭解 Cloud 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 類別執行個體將擷取指定種類的所有現有實體。物件的方法呼叫加上額外的篩選條件、祖系條件及排序順序後,可進而用於自訂查詢:

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 指定了只有完全不重複的結果會透過結果傳回。如有多個實體的投影屬性包含相同的值,這種方式只會傳回第一個結果。
針對重複的投影屬性值僅傳回第一個結果。
False
傳回所有結果。

執行個體方法

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)

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

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

迴圈的執行速度和 offsetlimit 的總和呈現線性關係。如果您知道要擷取的結果數,請務必設定確切的 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)

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

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

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

注意事項:相較於直接使用 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)

傳回符合查詢的結果數。比起實際擷取所有結果,這個方法的執行速度會依照固定比例加快,但執行時間會隨 offsetlimit 的總和呈現線性成長。建議您指定 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 GETPOST 參數,也可儲存於 Datastore 或 Memcache 中。您日後叫用相同的查詢時,可以透過 start_cursor 參數或 with_cursor() 方法提供這個字串,以便繼續從這個位置擷取結果。

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

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

with_cursor (start_cursor, end_cursor=None)

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

引數

start_cursor
Base64 編碼的游標字串,指定查詢的起始位置。
end_cursor
Base64 編碼的游標字串,指定查詢的結束位置。
本頁內容對您是否有任何幫助?請提供意見:

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

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