I'm trying to figure out how to organize app engine code with transactions. Currently I have a separate python file with all my transaction functions. For transactions that are closely related to entities, I was wondering if it made sense to use a @staticmethod
for the transaction.
Here is a simple example:
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)
It would be nice to have increment_n
associated with the entity definition, but I have never seen anyone do this so I was wondering if this would be a bad idea.
MY SOLUTION:
Following Brent's answer, I've implemented this:
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()
This way I can keep entity related code all in one place and I can easily use the transactional version or not as needed.
答案 0 :(得分:3)
是的,在这种情况下使用@staticmethod
是有意义的,因为该函数不使用类或实例(self
)。
是的,装饰者的顺序非常重要,如@Kekito后来的回答中所述。
答案 1 :(得分:1)
我后来遇到了this question的接受答案。这是一个引用:
装饰器将包装它正在装饰的函数。在这里,你的 add_cost函数被ndb.transactional包装所以一切都好 函数内部发生在事务的上下文中然后 它返回的方法由classmethod包装,返回一个 描述符对象。
因此,当您在类中应用多个装饰器时,则装饰器 例如classmethod或staticmethod应该是最好的。如果你 更改您将收到TypeError的顺序:未绑定的方法.... 如果其他装饰器不接受描述符,则为错误类型。
所以看起来装饰器的顺序非常重要。幸运的是,我按照正确的顺序排列了我的,但是对于遇到这个问题的其他人来说,这个更新了。