【发布时间】:2015-09-29 00:43:13
【问题描述】:
我正在尝试弄清楚如何使用事务来组织应用引擎代码。目前我有一个单独的 python 文件,其中包含我所有的事务函数。对于与实体密切相关的事务,我想知道使用@staticmethod 进行事务是否有意义。
这是一个简单的例子:
class MyEntity(ndb.Model):
n = ndb.IntegerProperty(default=0)
@staticmethod
@ndb.transactional # does the order of the decorators matter?
def increment_n(my_entity_key):
my_entity = my_entity_key.get()
my_entity.n += 1
my_entity.put()
def do_something(self):
MyEntity.increment_n(self.key)
将increment_n 与实体定义关联会很好,但我从未见过有人这样做,所以我想知道这是否是个坏主意。
我的解决方案:
按照布伦特的回答,我已经实现了这个:
class MyEntity(ndb.Model):
n = ndb.IntegerProperty(default=0)
@staticmethod
@ndb.transactional
def increment_n_transaction(my_entity_key):
my_entity = my_entity_key.get()
my_entity.increment_n()
def increment_n(self):
self.n += 1
self.put()
这样我可以将与实体相关的代码保存在一个地方,并且我可以根据需要轻松使用或不使用事务版本。
【问题讨论】:
-
为什么要使用静态方法,实际上为什么还要使用类方法?另外我希望你在调用 self.do_something 之后重新加载实例,因为当前的 self 显然已经过时了。您当前对 increment_n 的定义意味着可以传入任何键(即不是 MyEntity 键)。话虽如此,我一直将 classmethods 用于工厂等......我在这里的静态方法中看不到任何值,因为increment_n 的功能似乎非常特定于 MyEntity。
-
嗨@TimHoffman,我想使用静态方法的原因是事务只对某个实体类型进行操作,我希望事务的代码与其他代码位于同一位置与该实体有关。我的理解是我不能使用常规方法(因为我们需要传递密钥而不是实体)并且在这里使用类方法似乎没有帮助,因为事务不引用类。因此我想我会使用静态方法。
-
看起来你的方法很有意义。让我们翻转一下:您发现这种方法有问题吗?
-
@BrentWashburne,我还没试过。我对堆叠装饰器感到紧张,因为我是他们的新手,并且不确定正确的顺序是什么。希望在加入之前得到一些建议。
标签: python google-app-engine transactions