GAE allocate_ids和get_or_insert的问题

时间:2014-05-16 14:35:02

标签: python google-app-engine google-cloud-datastore app-engine-ndb

我正在尝试使用数据存储区在Python GAE应用程序中组合allocate_ids()和get_or_insert()。我最初使用

id = MyModel.allocate_ids(1)[0]
key = ndb.Key('MyModel', id)

m = MyModel.get_or_insert(key.id(), **{'text' : text})

但它提出了

"TypeError: name must be a string; received 1L". 

根据Guido在ndb get & get_or_insert how to use ? (alway raise Exception)上的回答,我必须将一个字符串传递给get_or_insert,但key.string()是None。我可以用

m = MyModel.get_or_insert(str(key.id()))

但它创造了一个新的实体,例如用密钥(MyModel,'1')代替分配的(MyModel,1)。

解决这个问题并将两者结合起来的最佳方法是什么?

-

更新:编辑以更正get_or_insert上的错误,如第一个评论主题

中所述

1 个答案:

答案 0 :(得分:2)

不要m = MyModel.get_or_insert(str(key.id()))创建一个完全不同的密钥,使用数字ID创建密钥。

如果你想使用数字id来get_or_insert的功能,那么你需要在没有str检查的情况下复制_get_or_insert_async中的代码,因为有一个显式检查名称是str。或者写一些简单的。

在交易中执行以下操作。

   id = MyModel.allocate_ids(1)[0]
   key = ndb.Key('MyModel', id)
   obj = key.get()
   if not obj:
       obj = MyModel(key=key)
       obj.put()

_get_or_insert_async内的代码效率会更高。

说完所有这些,如果你要分配id,那你为什么要使用get_or_insert呢?除非您随机添加数字ID,否则分配ID不会为您提供已分配的数字ID。这就是分配id的意图。

这使得带有分配id的get_or_insert的使用完全是多余的。

在您的代码中,您只使用id而不是其他值来执行get_or_insert,这似乎是无意义的操作。如果您使用的是分配ID,那么您将永远不会只创建一个新实体,然后您需要执行第二次更新属性。

你想要达到什么目标?