如何处理来自ndb.put_multi的错误

时间:2014-12-30 16:42:04

标签: python google-app-engine

GAE ndp.put_multi的文档严重缺乏。 NDB Entities and Keys - Python — Google Cloud Platform显示它返回一个键列表(list_of_keys = ndb.put_multi(list_of_entities)),但它没有说明失败。 NDB Functions没有提供更多信息。

通过代码(下面)深入了解,至少就目前而言,put_multi只聚合从异步方法返回的Future.get_result(),该方法本身委托给实体{{1}代码。现在,docs for the NDB Future Class表示将返回结果,否则将引发异常。但是,有人告诉我,如果特定put失败,结果将为None(我找不到任何相关的权威文档,但如果它类似于db.get那会有意义。)

the code

所以这一切归结为一些我无法找到答案的问题:

  1. 显然,返回值是一个列表 - 它是一个列表,其中一些元素可能是None?或者是使用例外吗?
  2. 当出现错误时,应该重新放置什么?是否可以重新放置所有实体(幂等),或者只返回那些返回值为put的实体(如果甚至是如何传达错误)?
  3. 错误的常见程度(一个答案:1/3000)?它们是否出现在日志中(因为我还没有看到)?有没有办法可靠地模拟测试错误?
  4. Usage of the function in an open source library意味着该操作是幂等的,但这就是它。 (Other usages don't even bother checking the return value or catching exceptions。)

    Handling Datastore Errors除了例外之外没有提及任何内容。

1 个答案:

答案 0 :(得分:3)

我同意您对代码的阅读:put_multi()以与put_async().get_result()相同的方式对错误做出反应。如果put()会引发异常,put_multi()也会出现,并且无法解决多个呼叫中的哪一个失败。我不知道put_multi()会为密钥列表中的某些条目返回None的情况。

您可以重新放置已放置的实体,假设自上次放置尝试后没有其他用户更新过这些实体。使用系统生成的ID创建的实体会更新其内存中的键,因此重新放置这些实体将覆盖现有实体而不会创建新实体。我不会完全称它为幂等因为重试会覆盖其他进程对这些实体的任何更新。

当然,如果您需要对结果进行更多控制,则可以在事务中执行此更新,但所有实体都需要位于同一实体组中才能使用原始事务。 (跨组事务最多支持五个不同的实体组。)事务期间的失败将确保在任何尝试失败时都不会创建或更新任何实体。

我不知道更新失败的一般错误率。此类故障最有可能包括争用错误或“热门平板电脑”(在太短的时间内对附近记录进行过多更新,导致超时),这将取决于应用行为。 API将所有此类错误报告为例外。

测试错误处理调用路径的最简单方法是包装Model类并使用测试模式行为覆盖方法。您可以更好地挖掘testbed使用的存根API,这可能有一种方法可以挂钩到低级别调用并模拟错误。 (我认为这不是testbed的直接功能,但您可以使用类似的技术。)