Python 使用事务更新实体的通用方法
我有一个GAE模型,其中包含几个使用事务更新实体的方法。大概是这样的:Python 使用事务更新实体的通用方法,python,google-app-engine,Python,Google App Engine,我有一个GAE模型,其中包含几个使用事务更新实体的方法。大概是这样的: class MyModel(ndb.Model): @staticmethod @ndb.transactional def update_foo(ekey): entity = ekey.get() entity.foo = "x" entity.put() @staticmethod @ndb.transactional
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")
为了清理我的代码,我在想,我可以集中对事务进行更新的代码。大概是这样的:
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")
这是一个合理的想法,还是这种方法中存在我没有考虑的危险?这是合理的。这实际上取决于您的用例 实际上,我也有类似的东西,但我越来越需要对每种实体类型的my
update_tx()
进行特殊处理,直到我的~10个模型中只有1或2个仍在使用它,因为几乎总是需要执行其他逻辑
- 如果我将用户的帐户状态从“停用”更新为“激活”,我需要执行一些查询,以查看他们是否完成了所有必需的入职步骤
- 如果用户更新了他们的电子邮件,我必须发送一个新的验证链接到新的电子邮件,然后才能更改
- 仅当实体处于特定状态时,某些字段才可编辑
- 如果用户提交的是新的开始日期和结束日期,我需要将旧的开始日期和结束日期保存在新对象中,以便于历史记录
- 等
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")
嗨,亚历克斯,谢谢你的见解。我正在努力弄清楚交易中需要做什么,以及在交易之前可以做什么。例如,tt似乎可以在事务之前验证表单数据,但其他操作不太清楚。当然可以。您将始终在模型中进行一些验证,事实上,ndb允许您在属性上设置验证器函数。实际上,我正在重构我是如何进行验证的,因为很多规则必须能够被管理员/客户服务代表进行更改(即用户只能在将来设置一个DATE时间,但是管理员需要能够追溯日期)。我目前的做法是在模型/事务中进行数据完整性验证,并基于模型之外的权限进行验证(以及时间戳->日期时间检查)。