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

时间:2018-03-27 10:48:27

标签: python-2.7 google-cloud-datastore

我正在尝试使用Google Cloud Datastore 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()

我做错了什么?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

简短回答: 正如@JimMorrison在回答中所述,您需要在数据存储区中开始批处理时调用batch.begin() method,除非您使用with语句,如the documentation for google.cloud.datastore.batch.Batch中所述。

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

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

根据有关数据存储区Batch class的文档,Batch类会覆盖Transaction类,因此除非您想要对基础Batch执行某些特定操作,您可能应该使用事务,如the documentation中所述,您可以在其中找到更多示例和最佳实践。这种做法比您正在使用的做法更受欢迎,它直接与Batch类一起使用,实际上它被Transaction覆盖。

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