0

很抱歉再次提出问题。

但是我在这里尝试做一些非常简单的事情,但我不知道该怎么做。文档给了我不起作用或适用的提示。

我收到一个 POST 请求并从中获取一个变量。它说“名字”。

我必须搜索我的实体对象(例如)并找出是否有一个具有相同名称的对象。没有,我必须用这个名字创建一个新的实体。看起来很容易,但我一直在失败。非常感谢任何帮助。

我的代码目前是这个:

 objects_qry = Object.query(Object.name == data["name"])

        if (not objects_qry ):
            obj = Object()
            obj .name =  data["name"]
            obj .put()

class Object(ndb.Model):
    name        = ndb.StringProperty()
4

2 回答 2

5

使用查询来执行此操作确实效率低下。

此外,您的代码可能不可靠,如果 name 不存在并且您同时有两个 name 请求,您最终可能会得到两条记录。而且您无法分辨,因为您的查询仅返回 name 属性等于某个值的第一个实体。

因为您期望名称只有一个实体,所以查询成本高且效率低。所以你有两个选择,你可以使用 get_or_insert 或者只是做一个 get,如果你现在有值创建一个新实体。

这里的任何方式都是使用名称作为键的一部分的几个代码示例。

name = data['name']
entity = Object.get_or_insert(name) 

或者

entity = Object.get_by_id(name)
if not entity:
    entity = Object(id=name)
    entity.put()
于 2013-10-02T22:57:17.407 回答
2

调用.query只是创建一个查询对象,它不会执行它,因此尝试将 is 作为布尔值进行评估是错误的。查询对象具有方法,fetch并且get分别返回匹配实体的列表或仅返回一个实体。

所以你的代码可以重写:

objects_qry = Object.query(Object.name == data["name"])
existing_object = objects_qry.get()

if not existing_object:
  obj = Object()
  obj.name = data["name"]
  obj.put()

也就是说,如果您真的关心名称的唯一性,Tim 在评论中关于使用 ID 而不是属性的观点是有道理的——上面的代码不会阻止两个同时请求创建具有相同名称的实体。

于 2013-10-02T17:43:01.157 回答