注意:强烈建议构建新应用的开发者使用 NDB 客户端库,它与 DB 客户端库相比具有多项优势,例如可通过 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")
为方便起见,Model
和 Expando
类有一个可返回 GqlQuery
实例的类方法 gql()
。此方法接受不含 SELECT
...
FROM
model-name
前缀的 GQL 查询字符串(该前缀的含义已暗含其中):
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)
-
返回一个用于遍历查询结果的可迭代对象。这样,您将可以使用参数设置指定查询的操作,并以迭代方式访问结果:
- 检索并舍弃
offset
参数指定的数量的结果。 - 检索并返回结果,结果的数量不超出
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
,则仅返回键,而不是完整实体。 与返回完整实体的查询相比,仅限于键的查询速度更快、费用更低。 - 投影
- 需要返回的属性名称的列表或元组。只返回具有指定属性的实体。如果未指定,则默认返回整个实体。
与返回完整实体的查询相比,投影查询速度更快、费用更低。
注意:指定此参数可能会更改查询的索引要求。
- start_cursor
- 开始查询的游标位置。
- end_cursor
- 结束查询的游标位置。
- 检索并舍弃
- get (read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY, read_policy=STRONG_CONSISTENCY)
-
执行查询并返回第一个结果,如果未找到结果,则返回
None
。 从数据存储区中检索至多一个结果;如果有 GQL 查询字符串的LIMIT
子句,则会被忽略。参数
- read_policy
- 指定所需的数据一致性级别的读取政策:
- STRONG_CONSISTENCY
- 保证返回最新的结果,但仅限于单个实体组。
- EVENTUAL_CONSISTENCY
- 可以跨越多个实体组,但有时可能会返回过时的结果。通常,最终一致性查询比强一致性查询的运行速度更快,但并不保证始终如此。
注意:全局(非祖先)查询会忽略此参数。
- deadline
- 在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户给出响应、重试操作、尝试其他操作,或将该操作添加到任务队列)。
- offset
- 返回第一条结果之前要跳过的结果数。
- keys_only
- 如果为
true
,则仅返回键,而不是完整实体。 与返回完整实体的查询相比,仅限于键的查询速度更快、费用更低。 - 投影
- 需要返回的属性名称的列表或元组。只返回具有指定属性的实体。如果未指定,则默认返回整个实体。
与返回完整实体的查询相比,投影查询速度更快、费用更低。
注意:指定此参数可能会更改查询的索引要求。
- 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
- 需要计数的结果数量上限。
注意:如果明确指定,则此参数将替换 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
GET
和POST
参数,也可以存储在 Datastore 或 Memcache 中。未来对同一查询的调用可以通过start_cursor
参数或with_cursor()
方法提供此字符串,以继续从此位置检索结果。注意:对尚未执行的查询调用此方法将引发
AssertionError
异常。注意:并非所有查询都与游标兼容;如需了解详情,请参阅 Datastore 查询页面。
- with_cursor (start_cursor, end_cursor=None)
-
在要从中检索结果的查询结果集中,指定起始位置和(可选)结束位置。表示起始和结束位置的游标字符串可以在先前调用查询之后调用
cursor()
来获得。当前查询必须与先前的调用完全相同,包括实体种类、属性过滤条件、祖先实体过滤条件以及排序顺序。参数
- start_cursor
- Base64 编码的游标字符串,指定开始查询的位置。
- end_cursor
- Base64 编码的游标字符串,指定结束查询的位置。