数据存储区函数

注意强烈建议构建新应用的开发者使用 NDB 客户端库,它与 DB 客户端库相比具有多项优势,例如可通过 Memcache API 进行自动实体缓存。如果您当前使用的是较早的 DB 客户端库,请参阅 DB 到 NDB 的迁移指南

google.appengine.ext.db 软件包中定义了本页面介绍的函数。

函数

allocate_ids (model, count)

在数据存储区中为某个数据存储区种类和父级组合分配一批 ID。

Datastore 的自动 ID 序列生成器将不会使用以这种方式分配的 ID,但这些 ID 可以在实体键中使用而不会产生冲突。

参数

model
要为其分配 ID 批量的 Model 键。这是一个常规,但只需要通过键的父级和种类来确定要使用的 ID 序列。
计数
要分配的 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)

在数据存储区中为某个数据存储区种类和父级组合异步分配一批 ID。

此函数与 allocate_ids() 相同,只是它会返回一个异步对象。您可以调用返回值的 get_result() 来阻止调用并返回结果。

参数

model
db.Model实例、或字符串充当可指定分配 ID 所采用的 ID 序列的模板。返回的 ID 应该仅在与此键具有相同父级(如果有)和种类的实体中使用。
计数
要分配的 ID 数。

返回分配的第一个和最后一个 ID 的元组。例如,如果您使用此函数分配了 10 个 ID,返回值的格式是 (1, 10),而不是已创建 ID 的完整列表。

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

使用特定端点分配一组 ID。一旦分配了这些 ID,您可以手动将其指定给新建的实体。

数据存储区的自动 ID 分配器从不分配已经(通过自动 ID 分配或通过显式“allocate_ids”调用)分配的键。因此,写入到给定键范围的实体永远也不会被覆盖。但是,在此范围中写入的实体如果具有手动指定的键,此实体可能会覆盖现有实体(或由不同请求写入的新实体),具体取决于返回的键的范围状态。

仅当您具有要保留的现有数字 ID 范围时才使用此函数(例如,批量加载已具有 ID 的实体)。 如果您不在意收到的是哪个 ID,请改用 allocate_ids()

参数

model
db.Model实例、或字符串充当可指定分配 ID 所采用的 ID 序列的模板。返回的 ID 应该仅在与此键具有相同父级(如果有)和种类的实体中使用。
开始
要分配的第一个 ID,是一个数字。
end
要分配的最后一个 ID,是一个数字。

返回KEY_RANGE_EMPTYKEY_RANGE_CONTENTIONKEY_RANGE_COLLISION中的一个。如果不是 KEY_RANGE_EMPTY,则表示在使用分配的键范围时存在潜在问题。

create_transaction_options(**kwargs)

创建用于控制事务执行的事务选项对象(TransactionOptions 类)。请将生成的对象作为第一个参数传递给 run_in_transaction_options() 函数。

参数

propagation
在从另一个事务中调用此事务函数时需要进行的操作:
ALLOWED
如果已经在事务中,则继续使用;如果不在事务中,则启动一个。

注意:如果使用此政策的函数引发异常,则捕获异常并提交外部事务可能不安全;该函数可能使外部事务处于错误状态。

必填
继续进行现有事务(如果有);如果不是,则抛出 BadRequestError 异常。

注意:如果使用此政策的函数引发异常,则捕获异常并提交外部事务可能不安全;该函数可能使外部事务处于错误状态。

INDEPENDENT
创建新事务,暂停任何现有事务。

注意:使用此政策的函数不应返回在新事务中读取的任何实体,因为这些实体在事务方面与外部事务不一致。

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)

从数据存储区中删除一个或多个 Model 实例。

参数

模型
要删除的一个 Model 实例、一个实体键或 Model 实例或实体键的列表(或其他可迭代的)。
deadline
在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户给出响应、重试操作、尝试其他操作,或将该操作添加到任务队列)。

put() 一样,如果指定了多个键,这些键可能位于多个实体组中。

如果在操作过程中发生错误,则始终会引发异常,即使某些实体实际上已被删除。如果调用返回而没有引发异常,则表示所有实体都已成功删除。

警告:在一次操作中删除多个实体不能保证删除操作将以原子方式进行,除非该操作是在事务内执行的。查询 Datastore 的其他进程可能会看到不一致的结果,即使查询是以高度一致性的方式执行的。

delete_async(models,deadline=60)

从数据存储区中异步删除一个或多个 Model 实例。

此函数与 delete() 相同,只是它会返回一个异步对象。您可以对返回值调用 get_result() 来阻止调用。

参数

模型
要删除的一个 Model 实例、一个实体键或 Model 实例或实体键的列表(或其他可迭代的)。
deadline
在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户给出响应、重试操作、尝试其他操作,或将该操作添加到任务队列)。

put() 一样,如果指定了多个键,这些键可能位于多个实体组中。

此函数会返回一个对象,可让您阻止调用的结果。

如果在操作过程中发生错误,则肯定会引发异常,即便某些实体其实已经删除。如果调用返回而没有引发异常,则表示所有实体都已成功删除。

警告:在一次操作中删除多个实体不能保证删除操作将以原子方式进行,除非该操作是在事务内执行的。查询 Datastore 的其他进程可能会看到不一致的结果,即使查询是以高度一致性的方式执行的。

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

从数据存储区获取具有给定键的特定 Model 实例。

参数

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)

从数据存储区中异步提取指定的 Model 实例。

此函数与 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 用于远程过程调用的序列化格式,它对于出于备份和恢复目的而序列化数据存储区对象来说十分有用。

注意:此函数将不同于开源协议缓冲区格式的(旧版)格式用于协议缓冲区,并且与开源实现不兼容。

参数

model_instance
要序列化的 Model 类(或子类)的实例。

以字节字符串的格式返回对象的协议缓冲区序列化。

model_from_protobuf(pb)

根据协议缓冲区序列化创建 Model 实例;如需了解详情,请参阅 model_to_protobuf()

参数

pb
model_to_protobuf()返回的协议缓冲区序列化。

返回适当 Kind 类的对象。如果 Kind 类不存在,则会引发 KindError 异常。如果对象对模型无效,则会引发 BadValueError 异常。

您可以像处理任何其他 Model 实例一样将新对象保存到Datastore,例如通过调用其 put() 方法。创建协议缓冲区时,该对象将保留自己已有的键。如果数据存储区中已存在拥有该键的对象,则保存反序列的对象时,系统将覆盖现有对象。

警告:如果对象的键使用系统分配的 ID,并且尚未为给定的路径和种类分配该 ID,则保存将成功,但不保留该 ID。未来创建的对象可以分配该 ID,且会覆盖较早的对象。为了安全起见,只能在对象被序列化时已存在这些对象的应用中恢复对象。

model_is_projection(model_instance)

如果指定的查询(model_instance)为投影查询而不是完整实体的查询,则返回 True

参数

model_instance
一种查询,您要检查以确定它是否是投影查询。

如果查询是投影查询,则返回 True;如果不是,则返回 False

put(models,deadline=60)

将一个或多个 Model 实例写入数据存储区中。

参数

模型
要存储的一个 Model 实例或 Model 实例列表。
deadline
在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户返回响应、重试操作、尝试其他操作或将操作添加到任务队列中)。

如果指定了多个 Model 实例,它们可能存储于多个实体组中。

如果在操作过程中发生错误,则肯定会引发异常,即便某些实体其实已经写入。如果调用返回而没有引发异常,则表示所有实体都已成功写入。

如果 models 由单个模型实例组成,则此函数会返回相应的对象。如果 models 是一个列表,则返回值是相应对象的列表。

警告:在一次操作中写入多个实体不能保证写入操作将以原子方式进行,除非该操作是在事务内执行的。查询 Datastore 的其他进程可能会看到不一致的结果,即使查询是以高度一致性的方式执行的。

put_async(models,deadline=60)

将一个或多个 Model 实例写入数据存储区中。

此函数与 put() 相同,只是它会返回一个异步对象。您可以对返回值调用 get_result(),以阻止调用和获取结果。

参数

模型
要存储的一个 Model 实例或 Model 实例列表。
deadline
在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户返回响应、重试操作、尝试其他操作或将操作添加到任务队列中)。

如果指定了多个 Model 实例,它们可能存储于多个实体组中。

如果在操作过程中发生错误,则肯定会引发异常,即便某些实体其实已经写入。如果调用返回而没有引发异常,则表示所有实体都已成功写入。

此函数返回一个可调用 get_result() 的异步对象。返回的结果与 put() 相同。

警告:在一次操作中写入多个实体不能保证写入操作将以原子方式进行,除非该操作是在事务内执行的。查询 Datastore 的其他进程可能会看到不一致的结果,即使查询是以高度一致性的方式执行的。

query_descendants(model_instance)

返回针对 Model 实例所有子项的查询结果。

参数

model_instance
您想要查找其子项的模型实例。
run_in_transaction(function,*args,**kwargs)

在单个事务中执行包含数据存储区更新的函数。 如果代码在事务过程中引发异常,则事务中进行的所有更新都将回滚。 您也可以使用 @db.transactional() 修饰器:

参数

函数
要执行的函数。
args
传递到函数的位置参数。
kwargs
传递到函数的关键字参数。

如果函数返回值,run_in_transaction() 会将该值返回给调用方。

如果该函数引发异常,事务将回滚。如果是 Rollback 异常,则不会重新引发;任何其他异常都会向调用者重新引发。

数据存储区会使用乐观锁定并重试事务。如果由该函数准备的事务无法提交,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)

在单个事务中执行包含数据存储区更新的函数,在发生争用时按指定的次数重试该事务。如果代码在事务过程中引发异常,则事务中进行的所有更新都将回滚。

除了指定重试次数之外,此函数的行为与 run_in_transaction() 相同。

参数

重试
实体组内发生争用事件时(多个用户同时尝试修改该组),调用该函数的最大次数。
函数
要执行的函数。
args
传递到函数的位置参数。
kwargs
传递到函数的关键字参数。
run_in_transaction_options(options,function,*args,**kwargs)

使用事务选项对象中指定的选项在单个事务执行包含数据存储区更新的函数。 如果代码在事务过程中引发异常,则事务中进行的所有 Datastore 更新都将回滚。

对于跨组 (XG) 事务,事务选项对象中的 xg 参数必须设置为 True

参数

options
包含此事务使用的设置的事务选项对象。要启用 XG 事务,必须将其 xg 参数设置为 True
函数
要执行的函数。
args
传递到函数的位置参数。
kwargs
传递到函数的关键字参数。

如果函数返回值,run_in_transaction_options() 会将该值返回给调用方。

如果该函数引发异常,事务将回滚。如果是 Rollback 异常,则不会重新引发;任何其他异常都会向调用者重新引发。

数据存储区会使用乐观锁定并重试事务。如果函数准备的事务无法提交,则 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 实例的字典表示形式。

参数

model_instance
要复制的 Model 实例。
dictionary
如果存在,则是合并模型数据的字典。Model 值覆盖字典中的值;系统会保留与 Model 实例中的字段不对应的字典条目。

装饰器

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

db 事务中运行函数。因此,您可以调用 func(),而不是调用 run_in_transaction(func)

参数

propagation
在从另一个事务中调用此事务函数时需要进行的操作:
ALLOWED
如果已经在事务中,则继续使用;如果不在事务中,则启动一个。

注意:如果使用此政策的函数引发异常,则捕获异常并提交外部事务可能不安全;该函数可能使外部事务处于错误状态。

必填
继续进行现有事务(如果有);如果不是,则抛出 BadRequestError 异常。

注意:如果使用此政策的函数引发异常,则捕获异常并提交外部事务可能不安全;该函数可能使外部事务处于错误状态。

INDEPENDENT
创建新事务,暂停任何现有事务。

注意:使用此政策的函数不应返回在新事务中读取的任何实体,因为这些实体在事务方面与外部事务不一致。

NESTED
(尚不支持)在现有事务中创建一个嵌套事务。
xg
如果为 True,则允许跨组 (XG) 事务。如果设置为非布尔值,则会引发 BadArgumentError 异常。
重试
尝试事务提交失败时的重试次数。
deadline
在使用错误代码取消查询之前,等待 Datastore 返回结果的最长时间(以秒为单位)。接受整数或浮点值。设置的值不能高于默认值(60 秒),但可以向下调整,以确保特定操作快速失败(例如,更快地向用户返回响应、重试操作、尝试其他操作或将操作添加到任务队列中)。
@db.non_transactional(allow_existing=True)

确保函数在 db 事务之外运行,即使从事务内部调用也是如此。

参数

allow_existing
如果为 True,则允许从现有事务中调用函数,如果为 False,则会抛出 BadRequestError 异常。