是否有关于如何将key_names列表传递给Model.get_or_insert()
的示例?
我的问题:
使用ParentLayer的方法我想让孩子们。
Child类的新(或可编辑)实体的key_names将来自以下列表:
namesList = ["picture1","picture2"]
所以我应该能够使用父类的方法构建一个key_names列表,如下所示:
class ParentLayer(db.Model):
def getOrMakeChildren(self, namesList):
keyslist = [ db.Key.from_path( 'Child' , name , parent = self.key() ) for name in namesList ]
接下来的问题是我只想根据上面定义的keylist
获取get_or_insert实体:
childrenEntitiesList = Child.get_or_insert(keyslist) # no works?
以下尝试也没有奏效:
#childrenEntitiesList = Child.get_or_insert(keyslist, parent = u'TEST')
#childrenEntitiesList = Child.get_or_insert(keyslist, parent=self.key().name() )
#childrenEntitiesList = Child.get_or_insert(keyslist, parent=self.key()
答案 0 :(得分:3)
get_or_insert
必须使用事务才能以原子方式返回或创建所请求的实体,并且您无法在多个实体上执行单个事务。此外,get_or_insert接受构造函数的关键字参数,并且没有简单的方法为每个参数指定不同的集合。
如果你只想get_or_insert多个键,你可以这样做:
entities = [Child.get_or_insert(k) for k in keylist]
如上所述,这将需要每个实体的交易。如果您希望相关实体通常存在,则替代版本的get_or_insert可能对您更有用(也更有效):
def _get_or_insert_tx(key, properties):
"""When run in a transaction, fetches or creates an entity atomically."""
entity = db.get(key)
if not entity:
entity = db.class_for_kind(key.kind())(key=key, *properties)
entity.put()
return entity
def get_or_insert_multiple(args):
"""Fetches or creates multiple entities.
Args:
args: A list of (key, dict-of-properties) tuples
Returns:
A list of entities, in the same order as args.
"""
# First, try and fetch them in a batch, outside the transaction
entities = db.get([x[0] for x in args])
# Now, transactionally create or fetch each missing one
for i in range(len(entities)):
if entities[i] is None:
entities[i] = db.run_in_transaction(_get_or_insert_tx, *args[i])
return entities
此代码将首先尝试批量提取您要创建的所有实体,然后仅针对尚不存在的实体执行事务。在最好的情况下,它只进行一次批量处理;在最坏的情况下,它会为每个实体执行批处理后跟事务。请注意,与内置的get_or_insert不同,这个获取键而不是键名 - 因为这是您使用的语法。
这里正在使用:
entities = get_or_insert_multiple([(k, {}) for k in keys])
请注意每个实体的空字典,因为您没有指定要传递给新实体的构造函数的任何属性。