当多个人可能尝试同时创建实体时,我正在尝试为实体创建一个没有冲突的数字ID(应用程序用户会看到并使用该ID,因此理想情况下它将低于6位数长度 - 自动分配的ID可能是不可接受的)。
我目前的解决方案似乎过于繁琐,甚至可能无法解决冲突。
我有一个ID计数器,我将其存储在另一个App实体中:
class App(ndb.Model):
# counter to store number of projects
num_projects = ndb.IntegerProperty(default = 0)
实际项目:
class Project(ndb.Model):
date_created = ndb.DateTimeProperty(auto_now_add = True)
last_modified = ndb.DateTimeProperty(auto_now = True)
owner = ndb.KeyProperty(required = True)
owner_name = ndb.StringProperty(required = True)
name = ndb.StringProperty(required = True)
和用于创建项目的处理程序类:(可以同时调用)
def make_new_project(self):
pdt = App.by_id('pdt')
pdt.num_projects = pdt.num_projects + 1
if not Project.by_id(pdt.num_projects):
project = Project(id=pdt.num_projects)
project.put()
pdt.put()
return project
else:
return self.make_new_project()
处理程序的意图是检查项目ID是否已被使用(有人在我检索App计数器之后确实放了一个新项目),如果没有,用新计数器编号创建项目,然后将两者都存储到DB。
我觉得这仍然有点儿,可能会导致竞争条件?有没有更好的办法?我应该预先分配密钥吗?如果是,我该怎么做?我是否将分配的密钥存储到我的App模型中以便以后检索?
我很容易对某些功能的运行时感到困惑。如果我添加一个函数来为我的main.py分配密钥,那么每次启动一个新实例时都会运行吗?
为了澄清下面提出的一些问题,项目应该可以通过nuerics找到,因为现有系统的用户更喜欢在与其他员工交谈时引用项目编号...即:“我正在打电话给项目13670“并且他们可以通过顺序编号判断哪个项目较旧,否则我只会生成一个随机的5位数字,并在分配之前检查它是否尚未使用。
任何帮助,澄清等......都将不胜感激。
答案 0 :(得分:1)
使用NDB生成的密钥:它是为多个并发而设计的,并且做得很好。
然后将生成的密钥转换为更友好的密钥:base36应该可以解决问题。
例如:
9999999999999999 (16 length)
变为
2QGPCKVNG1R (11 length)
具体做法是:
friendlyValue = base36encode(entity.key.id())