繁体   English   中英

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

[英]ndb.ComputedProperty from ndb.DateTimeProperty(auto_true=now) first call error

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

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设置对其进行了测试,并且工作正常。

任何帮助都将是巨大的!

找出问题,这实际上是一个简单的解决方案。 我只是编辑线

updatedDate = ndb.DateTimeProperty(auto_now=True)

包括默认参数

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

还必须导入datetime模块

import datetime

更新后,便可以正确创建对象。 现在,它不仅可以正常运行,而且可以将updateDate的初始值设置为当前日期和时间。 更糟糕的是,auto_now参数不会自动执行此操作。

感谢所有花费您时间为我提供此解决方案的人!

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

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

我本来希望使用_pre_put_hook一个更“不用考虑”的解决方案,但是在测试中,它似乎在ComputedProperty time ComputedProperty之前没有被调用。

问题是DateTimeProperty(auto_now = True)在放置时间之前无法解析。 与计算属性相同。 正如您所发现的,ComputedProperty也同时被评估。

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

您应该如何解决?

不知道,在理论上你可以使用一个工厂来创建Series实体每次你需要创建一个时间,并明确设置日期时间,当你创建对象。 这意味着当您放置对象时,ComputedProperty将得到解析,并且可能只用了不到一秒钟的时间。

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

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

这可能意味着您应该使用通常调用的Series方法update ,而不是put,而在put之前会显式设置updateDate。

def update(self):
   self.updatedDate = datetime.now()
   self.put()

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

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

凌乱-我知道;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM