1

我有一种“客户”。当即将插入新的“客户”时,我想运行一个锁定整个 Kind 的事务。事务将首先查询以检查新的“客户”名称是否不存在,然后事务的第二部分在未找到匹配项时运行插入。通过这种方式,我强制执行唯一约束(并将操作限制为每秒大约 1 次插入)。

将我的所有“客户”实体放在同一个实体组中,我不满意的解决方案是创建一个名为“EntityGroups”的种类,其中包含一条名为“CustomersGroup”的记录。每次都将这一记录用作新创建的“客户”实体的父级,从而将整个种类分组到一个实体组中。

我的问题是:我担心使用诸如“客户组”之类的虚拟记录,因为如果发生任何事情并且丢失或删除,我无法将任何新的“客户”实体分配给同一组!我想最好为每个“客户”实体的父级分配一个静态的任意父级,例如“1111111”?我认为术语是“虚拟根实体”,我该怎么做?

请就我如何最好地处理这个问题提供任何建议!

4

4 回答 4

3

为什么不使用:NDB 的 get_or_insert:以事务方式检索现有实体或创建新实体。

https://developers.google.com/appengine/docs/python/ndb/modelclass#Model_get_or_insert

于 2012-10-30T16:30:34.283 回答
3

您的CustomerGroup记录不需要存在就可以作为父母。只需手动创建它的键并将其作为父项分配给相关记录。

如果它不存在,您不必担心它会被删除!

当您创建一个模型并将另一个模型设置为其父模型时,系统不会检查(也不需要)该模型是否确实存在。

例如:

rev_key = ndb.Key('CustomerGroup', '11111', 'Customer', 'New_Customer_Name')

然而,键为:的模型('CustomerGroup', '11111')实际上并不存在,但它仍然可以在祖先链中。

于 2012-10-30T18:31:49.197 回答
1

GrantsV,您可以通过为每个唯一约束创建代理实体并使用跨组事务通过正常写入提交约束来实现此目的。

class UniqueConstraint(db.Model):
  # Consider adding a reference to the owner of the constraint.
  @db.transactional(propagation=db.MANDATORY, xg=True)
  @classmethod
  def reserve(cls, kind, property, value):
    key = cls.__get_key(kind, property, value)
    if db.get(key):
      raise Exception  # Already exists
    cls(key=key).put()

  @db.transactional(propagation=db.MANDATORY, xg=True)
  @classmethod
  def release(cls, kind, property, value):
    db.delete(cls.__get_key(kind, property, value))

  @classmethod
  def __get_key(cls, kind, property, value):
    # Consider using a larger entity group.
    return db.Key.from_path(cls.kind(), '%s:%s:%s' % (kind, property, value))
    # To restrict to 1 insert per second per kind, use:
    # return db.Key.from_path(cls.kind(), kind, cls.kind(), '%s:%s' % (property, value))
于 2012-10-30T20:27:08.853 回答
0

您可以创建一个父实体,如下所示:

class CustomerParent(ndb.Model):
    pass

然后你实例化并存储你的父实体:

customers_parent = CustomerParent()
customers_parent.put()

最后,当您创建所有客户实体时,指定父实体:

a_customer = Customer(parent=customers_parent.key, ...)
a_customer.put()

希望这可以帮助!

于 2012-10-30T15:44:11.370 回答