我有一种'客户'。我想运行一项交易,当即将插入新的"客户"时,可以锁定整个类型。交易将首先查询检查新的"客户"名称尚不存在,然后如果找不到匹配项,则交易的第二部分运行插入物。这样,我正在执行独特的约束(还将操作限制在每秒大约1个插入物)。
我在同一实体组中获取所有"客户"实体的不令人满意的解决方案是创建一种称为" EntityGroups"的类别,其中一个名为" CustomersGroup"的记录。每次都使用该记录作为新创建的"客户"实体的父母,从而将整个类型分组为一个实体组。
我的问题是:我担心使用诸如" CustomerGroup"之类的幻影记录,因为如果发生任何事情并丢失或删除了,我将无法将任何新的"客户"实体分配给同一组!我想最好将每个"客户"实体的父母分配为静态任意父母,例如" 1111111"?我认为术语是"虚拟根实体",我该怎么做?
请帮助有关如何最好地处理的任何建议!
您为什么不使用:ndb的get_or_insert:交易检索现有实体或创建新实体。
https://developers.google.com/appengine/docs/python/ndb/modelclass#model_get_or_or_insert
您的CustomerGroup
记录不需要存在即可充当父母。只需手工创建它的密钥,然后将其作为父母分配到所讨论的记录。
如果不存在,您不必担心它会被删除!
创建模型并设置另一个模型时,该系统实际上根本不存在(也不需要)系统。
所以:
rev_key = ndb.Key('CustomerGroup', '11111', 'Customer', 'New_Customer_Name')
然而,一个具有:('CustomerGroup', '11111')
的键的模型实际上并不存在,但它仍然可以在祖先链中。
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))
您可以创建一个父实体,例如:
class CustomerParent(ndb.Model):
pass
然后您实例化并存储您的父实体:
customers_parent = CustomerParent()
customers_parent.put()
最后,当您创建所有客户实体时,您指定父母:
a_customer = Customer(parent=customers_parent.key, ...)
a_customer.put()
希望这会有所帮助!