我正在尝试使用数据存储区在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上的错误,如第一个评论主题
中所述答案 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,那么您将永远不会只创建一个新实体,然后您需要执行第二次更新属性。
你想要达到什么目标?