在App Engine中动态修改实体模型的危险



我有一个类,我所有的实体定义继承:

class Model(db.Model):
    """Superclass for all others; contains generic properties and methods."""
    created = db.DateTimeProperty(auto_now_add=True)
    modified = db.DateTimeProperty(auto_now=True)

出于各种原因,我希望能够偶尔修改实体而不改变其修改属性。我找到了这个例子:

Model.__dict__["modified"].__dict__["auto_now"] = False
db.put(my_entity)
Model.__dict__["modified"].__dict__["auto_now"] = True

当我在本地测试时,它工作得很好。我的问题是:这是否会对任何其他代码产生更广泛的影响,这些代码恰好在Model被更改的一小段时间内保存实体?我可以看到这会导致难以置信的令人困惑的bug。但也许这个小变化只影响当前进程/线程或其他什么?

任何其他请求进入相同的实例并在put正在进行时被处理,也将获得auto_now=False,虽然不太可能

其他要考虑的事情

在此代码周围没有try块,如果在put()期间出现超时或错误,您的代码将使模型处于auto_now=False的修改状态。

我个人认为这是个坏主意,而且肯定会成为错误的来源。

有很多方法可以在不操纵模型的情况下实现这一点,

考虑将默认行为设置为auto_now=False,然后使用两个方法进行更新。主要方法在执行put()之前将修改的时间设置为datetime.now(),例如save()和save_without_modified()

一个更好的方法是在你的类中重写put(),然后设置修改,然后调用super put(),让put()接受一个新的参数,比如modified=False,这样你就不用在调用super之前设置修改日期。

最后,您可以使用_pre_put钩子在put()调用之前运行代码,但是您需要以某种方式注释实例,以便_pre_put方法可以确定是否需要设置修改。

我认为这些策略都比入侵模型安全得多

最新更新