【问题标题】:Creating Fixed Width ID Based On Serial Number in Python NDB Datastore在 Python NDB 数据存储中基于序列号创建固定宽度 ID
【发布时间】:2014-09-30 21:48:11
【问题描述】:

我有一个名为 UserModel 的模型,我知道它永远不会超过 10000 个实体。我在 UserModel 中没有任何独特的东西可以用来创建密钥。因此我决定使用这种格式为 USRXXXXX 的字符串键。

其中 XXXXX 代表序列号。例如 USR00001、USR12345

因此我选择了以下方式来生成 ID

def generate_unique_id():
    qry = UserModel.query()
    num = qry.count() + 1
    id = 'USR' + '%0.5d' % num
    return id

def create_entity(model, id, **kwargs):
    ent = model.get_or_insert(id, **kwargs)
    # check if its the newly created record or the existing one
    if ent.key.id() != id:
        raise InsertError('failed to add new user, please retry the operation)
    return True

问题:

  1. 这是实现固定宽度序列计数的最佳方法吗?这个解决方案是否是最优的和惯用的?

  2. 像上面那样使用 get_or_insert 可以保证我永远不会有重复的记录。

  3. 它会增加我的帐单,因为计算我在没有任何过滤器的情况下执行 UserModel.query() 的记录数。在某种程度上,我正在获取所有记录。或者直到我在 qry 对象上使用 fetch api 才会出现计费?

【问题讨论】:

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


    【解决方案1】:

    由于您只需要 UserModel 实体的唯一键,我不太明白为什么需要手动创建键。 App Engine 自动生成的 ID 保证是唯一的。

    关于您的问题,我们有以下几点:

    1. 我认为不是。也许你应该先分配 ID(查看Using Numeric Key IDs 部分),订购它,然后使用它。

    2. 尽管get_or_insert 是强一致的,但您执行的查询 (qry = UserModel.query()) 不是。因此,您可能会导致覆盖现有实体。有关最终一致性的更多信息,请查看here

    3. 不,它不会增加您的账单。当您执行Model.query().count() 时,引擎盖下的数据存储会执行Model.query().fetch(keys_only=True) 并计算结果数。仅限键的查询会生成小型数据存储操作,这些操作基于 Google 的最新定价变化是不计费的。

    【讨论】:

      【解决方案2】:
      1. 可能不会。如果您的 UserModel 实体具有 ancestors 以获得更强的一致性,您可能会成功地尝试执行此操作。

      2. 不,get_or_insert 不保证您不会有重复。尽管在这种情况下您不太可能有重复,但您更有可能丢失数据。假设您要插入两个没有祖先的实体 - Model.query().count() 可能需要一些时间来反映第一个实体的创建导致第二个实体具有与第一个实体相同的 ID 并因此覆盖它(即您最终得到第二个实体只有具有第一个 ID 的实体)。

      3. Model.query().count()len(Model.query().fetch()) 的缩写(尽管进行了一些优化),因此每次生成 ID 时都会获取所有实体。

      【讨论】:

      • 但是使用 parent 会将 UserModel 中的每个实体放在同一个实体组中,因此会有写入速度限制。仅仅获得一个顺序 ID 不是要付出巨大的代价吗?因为对于应用程序的其余部分,我对最终的一致性很好。
      • 有什么办法可以避免在 UserModel 中创建新记录的父查询,并且仍然可以保证没有重复或数据丢失?
      • 分片计数器是一种方法,但为此我必须创建一个单独的模型来存储计数。
      • 不幸的是,我不知道有任何好的/可扩展的方式来实现自动增量,但请查看此讨论以获取一些想法:stackoverflow.com/questions/3985812/…
      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      相关资源
      最近更新 更多