2017-08-11 30 views
0

我有一个GAE模型,有几个方法用事务更新实体。这样的事情:用事务更新实体的通用方法

class MyModel(ndb.Model): 

    @staticmethod 
    @ndb.transactional 
    def update_foo(ekey): 
     entity = ekey.get() 
     entity.foo = "x" 
     entity.put() 

    @staticmethod 
    @ndb.transactional 
    def update_bar(ekey): 
     entity = ekey.get() 
     entity.bar = "y" 
     entity.put() 

为了清理我的代码,我想,我可以集中更新交易的代码。事情是这样的:

class MyModel(ndb.Model): 

    @staticmethod 
    @ndb.transactional 
    def update_tx(ekey, **kwargs): 
     entity = ekey.get() 
     for prop, value in kwargs.iteritems(): 
      setattr(entity, prop, value) 
     enitty.put() 

    def update_foo(self): 
     self.update_tx(self.key, foo="x") 

    def update_bar(self): 
     self.update_tx(self.key, bar="y") 

这是一个合理的想法,或者是否有这种做法的危险,我还没有考虑?

回答

1

这是合理的。这真的取决于你的用例。

我实际上有类似的地方,但越来越多,我必须特殊情况下我的update_tx()为每个实体类型的点,只有1或2我~10模型仍然使用它,因为几乎总是其他需要执行的逻辑。

  • 如果我将用户的帐户状态从“停用”更新为“激活”,则需要执行一些查询以查看他们是否完成了所有必需的入职步骤。
  • 如果用户更新他们的电子邮件,我要送一个新的验证链接到新的电子邮件,才可以改变
  • 某些字段仅可编辑,如果实体处于某种状态
  • 如果用户提交一个新的开始日期和结束日期,我需要保存在新对象旧的开始日期和结束日期为历史目的

这种逻辑可能发生这种功能之外,但我常常想,要在发生同一笔交易。

那一边,有一两件事似乎没有处理的需要更新了一批在一个单一的交易主体,让你的伪代码将需要查看更多类似这样的,如果这对你很重要:

class MyModel(ndb.Model): 

    def update_properties(self, **kwargs): 
     for prop, value in kwargs.iteritems(): 
      setattr(self, prop, value) 

    @staticmethod 
    @ndb.transactional(xg=True) 
    def update_txs(keys, updates): 
     # keys is an array of ndb.Key()s, 
     # updates is an array of the same size, containing **kwargs for each key 
     entities = ndb.get_multi(keys) 
     for index, entity in enumerate(entities): 
      entity.update_properties(**updates[index]) 
     ndb.put_multi(entities) 

    @classmethod 
    def update_tx(cls, ekey, **kwargs): 
     cls.update_txs([ekey], [kwargs]) 

    def update_foo(self): 
     self.update_tx(self.key, foo="x") 

    def update_bar(self): 
     self.update_tx(self.key, bar="y") 
+0

嗨,亚历克斯,感谢您的见解。我正在努力弄清楚交易中需要什么以及交易之前会有什么。例如,tt似乎可以在事务之前完成验证表单数据,但其他操作不太清楚。 –

+0

当然可以。您将始终在模型中进行一些验证,实际上ndb允许您在属性上设置验证器函数。我实际上正在重构我如何进行验证,因为许多规则必须能够被管理员/客户服务代表改写(即用户只能将日期时间设置为将来,但需要管理员能够支持事物)。我现在要做的路线是将数据完整性验证放入模型/事务中,并根据模型外的权限进行验证(以及时间戳 - >日期时间检查)。 – Alex