GAE/P transaction using static method

时间:2015-09-29 00:43:13

标签: python google-app-engine transactions

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.

2 个答案:

答案 0 :(得分:3)

是的,在这种情况下使用@staticmethod是有意义的,因为该函数不使用类或实例(self)。

是的,装饰者的顺序非常重要,如@Kekito后来的回答中所述。

答案 1 :(得分:1)

我后来遇到了this question的接受答案。这是一个引用:

  

装饰器将包装它正在装饰的函数。在这里,你的   add_cost函数被ndb.transactional包装所以一切都好   函数内部发生在事务的上下文中然后   它返回的方法由classmethod包装,返回一个   描述符对象。

     

因此,当您在类中应用多个装饰器时,则装饰器   例如classmethod或staticmethod应该是最好的。如果你   更改您将收到TypeError的顺序:未绑定的方法....   如果其他装饰器不接受描述符,则为错误类型。

所以看起来装饰器的顺序非常重要。幸运的是,我按照正确的顺序排列了我的,但是对于遇到这个问题的其他人来说,这个更新了。