ndb.ComputedProperty来自ndb.DateTimeProperty(auto_true = now)第一次调用错误

时间:2013-08-11 08:29:41

标签: python google-app-engine datetime

我有一个ndb.Model,它有一个ndb.DateTimeProperty和一个ndb.ComputedProperty,它使用ndb.DateTimeProperty创建一个时间戳。

import time
from google.appengine.ext import ndb

class Series(ndb.Model):
    updatedDate = ndb.DateTimeProperty(auto_now=True)
    time = ndb.ComputedProperty(lambda self: time.mktime(self.updatedDate.timetuple()))

我遇到的问题是第一次调用.put()(seriesObj只是一个从Series类创建的对象)

seriesObj.put()

此时ndb.DateTimeProperty为空。我收到以下错误:

File "/main.py", line 0, in post series.put()
time = ndb.ComputedProperty(lambda self: time.mktime(self.updatedDate.timetuple()))
AttributeError: 'NoneType' object has no attribute 'timetuple'

我可以说这只是因为没有设置ndb.DateTimeProperty但是我不知道在ndb.ComputedProperty去读它之前如何设置它。

这不是ndb.ComputedProperty的问题,因为我已经使用ndb.DateTimeProperty集进行了测试,它运行正常。

任何和所有帮助都会很棒!

3 个答案:

答案 0 :(得分:1)

想出问题,它实际上是一个简单的解决方案。我只是编辑了这行

updatedDate = ndb.DateTimeProperty(auto_now=True)

包含默认参数

updatedDate = ndb.DateTimeProperty(auto_now=True, default=datetime.datetime.now())

还必须导入日期时间模块

import datetime

更新后,可以无错误地创建对象。现在它不仅会运行而不会出错,还会将updateDate的初始值设置为当前日期和时间。为了坏,auto_now参数不会自动执行此操作。

感谢所有花时间帮助我解决这个问题的人!

答案 1 :(得分:1)

在对此问题进行进一步调查之后,避免在导入模块时评估默认值。我刚刚在创建新updatedDate时设置了Series的初始值。

import datetime
series = Series(updatedDate = datetime.datetime.now())
series.put()

我希望使用_pre_put_hook更多的“不要考虑”解决方案,但在测试中,似乎在评估time ComputedProperty之前没有调用它

答案 2 :(得分:0)

问题是DateTimeProperty(auto_now = True)在放置时间之前没有解决。与计算属性相同。如您所知,ComputedProperty也会同时进行评估。

然而,这是疣,声明的顺序似乎没有被保留,(我在尝试自动生成基于模型属性的表单时发现了这一点)。属性不存储在OrderedDictionary中,因此无法保证顺序,因此在解析udpatedDate之前,您会发现ComputedProperty time正在解析。

你应该如何解决这个问题?

不确定,理论上,每次需要创建Series实体时,都可以使用Factory创建update实体,并在创建对象时显式设置DateTime。这意味着当您放置对象时,ComputedProperty将被解析,并且可能只会出现一小段时间。

但是,这可能无法确保在将来的更新中正确评估ComputedProperty。 ComputedProperty很可能会使用旧值而不是updatedDate的新值,因为您仍然无法强制执行属性评估的顺序。

我个人认为这是对ndb Model类的一个bug或急需的增强。

这可能意味着你应该使用一个系列说def update(self): self.updatedDate = datetime.now() self.put() 的方法,你总是调用它而不是在调用put之前显式设置updateDate的方法。

{{1}}

可能更好的方法是在调用put之前使用pre_put挂钩显式设置udpateDate。我没有对此进行测试,以确保在属性评估之前调用它,但我的猜测是

https://developers.google.com/appengine/docs/python/ndb/modelclass#Model__pre_put_hook

凌乱 - 我知道; - )