通过数字 ID 创建唯一的应用程序引擎数据存储实体,而不会发生冲突 - python



当多个人可能尝试同时创建实体时,我正在尝试为没有冲突的实体创建一个数字 id(该应用程序用户将看到和使用 id,因此理想情况下它的长度将低于 6 位 - 自动分配的 ID 可能不被接受)。

我目前的解决方案似乎过于繁琐,甚至可能无法解决冲突。

我有一个 ID 计数器,我存储在不同的应用实体中:

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。

我觉得这仍然有点麻烦,可能会导致比赛条件??有没有更好的方法?我应该预先分配密钥吗?如果是,我该怎么做?我是否将分配的密钥存储到我的应用模型中以供以后检索?

我很容易对某些函数的运行时间感到困惑。如果我添加一个函数来为我的 main.py 分配密钥,它是否在每次启动新实例时运行?

为了澄清下面提出的一些问题,这些项目应该可以由 nuerics 找到,因为现有系统的用户在与其他员工交谈时更喜欢引用项目编号......即:"我正在打电话讨论项目 13670",他们可以通过顺序编号来判断哪个项目较旧,否则我只会生成一个随机的 5 位数字并在分配之前检查它尚未使用。

任何帮助,澄清等......将不胜感激。

使用NDB生成的密钥:它专为多个并发而设计,并且做得很好。

然后将生成的密钥转换为更友好的密钥:base36 应该可以解决问题。

例如:

9999999999999999 (16 length)

成为

2QGPCKVNG1R (11 length)

具体说来:

friendlyValue = base36encode(entity.key.id())

最新更新