我正在尝试执行下面的代码。有时它工作正常。但有时它不起作用。
@db.transactional
def _add_data_to_site(self, key):
site = models.Site.get_by_key_name('s:%s' % self.site_id)
if not site:
site = models.Site()
if key not in site.data:
site.data.append(key)
site.put()
memcache.delete_multi(['', ':0', ':1'], key_prefix='s%s' %
self.site_id)
我收到了错误:
File "/base/data/home/apps/xxxxxxx/1-7-1.366398694339889874xxxxxxx.py", line 91, in _add_data_to_site
site.put()
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1070, in put
return datastore.Put(self._entity, **kwargs)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 579, in Put
return PutAsync(entities, **kwargs).get_result()
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
return self.__get_result_hook(self)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1569, in __put_hook
self.check_rpc_success(rpc)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1224, in check_rpc_success
raise _ToDatastoreError(err)
BadRequestError: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXG
如果我只更改一个实体(models.Site
),为什么我会收到跨群组交易错误?
答案 0 :(得分:1)
跨群组交易错误是指使用的entity groups,而不是使用的类型(此处Site
)。
当它发生时,这是因为您正在尝试对具有不同父项的实体进行交易,因此将它们放在不同的实体组中。
您应该停止使用db
并将代码移至ndb
,尤其是因为您似乎处于开发阶段。
答案 1 :(得分:1)
如果在get_by_key_name()查询中指定parent = None,这是否有效?
基本上,为了使用事务,事务中的所有实体必须共享相同的父级(即,您使用一个父级进行查询,并使用同一父级创建新实体),或者必须使用XG事务。您看到了一个问题,因为您没有指定父级。
您可能需要创建人工实体以表现为父母,以便做您正在尝试做的事情。
答案 2 :(得分:1)
我有同样的问题。通过单步执行客户端代码,我做了以下两个观察:
1)设置(无)的父级似乎仍然表示该类型的父级,即使没有选择该父级的特定记录。
2)您的交易也将包括所有ReferenceProperty属性。
因此,理论上,如果您没有在任何影响的类型上声明父级(通过省略或设置为(None)),则应该获得跨组事务异常(如果至少有)两个(因为如果你使用A类和B类,看起来你正在使用两个不同的实体组,A记录和B记录), - 以及任何ReferenceProperty引用的任何类型属性。
要解决此问题,您必须至少创建一个没有任何属性的类,可以将其设置为所有先前无父记录的父级,以及它们声明的所有ReferenceProperty属性的父级。
如果这还不够,则设置跨群组交易的标志。
此外,对我来说,例外的文本是:“需要明确指定跨组事务”(复数“组”)。我有Python AppEngine客户端的1.7.6版本。
如果适合您的情况,请提供此答案。
答案 3 :(得分:1)
如日志中所述:“需要明确指定跨组事务”。 尝试使用
指定它@db.transactional(xg=True)
而不是:
@db.transactional