数据存储:批处理必须进行到 put()

Datastore: Batch must be in progress to put()

我正在尝试使用 Google 云数据存储 API 客户端库在数据存储上上传带有批处理的实体。我的版本是1.6.0

这是我的代码:

from google.cloud import datastore
client = datastore.Client()

batch = client.batch()

key = client.key('test', 'key1')
entity = datastore.Entity(
    key,
    exclude_from_indexes=['attribute2'])
entity.update({
    'attribute1': 'hello',
    'attribute2': 'hello again',
    'attribute3': 0.98,
})
batch.put(entity)

当我执行 batch.put():

时出现此错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/google/cloud/datastore/batch.py", line 185, in put
    raise ValueError('Batch must be in progress to put()')
ValueError: Batch must be in progress to put()

我做错了什么?

如果您不在上下文中执行放置,则需要显式调用 batch.begin(),即使用 with 关键字。

简答: 正如@JimMorrison 在他的回答中所述,您需要调用 batch.begin() method when beginning a batch in Datastore, unless you are using the with statement, as explained in the documentation for google.cloud.datastore.batch.Batch.


长答案:简短答案中的答案有效,但是直接使用批处理根据文档,这不是推荐的方法。 Datastore documentation 提供了一些有关如何使用批处理操作的信息,区分两种类型的批处理操作:

  • Non-transactional batch: 这些是一些预定义的方法(通常有 _multi 附录,表示它将同时处理多个实体)允许在单个 Datastore 调用中对多个对象进行操作。这些方法是get_multi()put_multi()delete_multi(),但它们不是transactionally执行的,即可能只有请求中的某些操作有如果发生错误,则成功结束。
  • 事务:保证永远不会部分应用的原子操作,即要么应用所有操作,要么none(如果发生错误)。这是一个很好的功能,可以根据您尝试执行的操作时间派上用场。

根据有关 Datastore Batch class, the Batch class is overridden by the Transaction class, so unless you want to perform some specific operations with the underlying Batch, you should probably work with transactions instead, as explained in the documentation 的文档,您可以在其中找到更多示例和最佳实践。这种做法优于您正在使用的做法,后者直接使用 Batch class,实际上被 Transaction.

覆盖

TL;DR: batch.begin() 将解决您代码中的问题,因为您需要使用 _IN_PROGRESS status 初始化批处理。但是,如果你想让你的生活更轻松,并通过事务抽象地使用批处理,并提供更好的文档和示例,我建议改用事务。