【问题标题】:ndb query error with datetime field - Google App Engine带有日期时间字段的 ndb 查询错误 - Google App Engine
【发布时间】:2013-02-19 11:18:55
【问题描述】:

我遇到了问题,没有找到任何相关信息。

我在我的模型中这样定义一个字段。

class Dates(ndb.model):
    ...
    date = ndb.DateTimeProperty(required = True) # I want to store date and time
    ...

稍后我尝试查询(现在我想要一天的所有日期,我不介意时间):

kl = Dates.query(ndb.AND(Dates.date.year == year,
                         Dates.date.month == month,
                         Dates.date.day == day),
                 ancestor = customer.key).fetch(keys_only = True)
dates = ndb.get_multi(kl)

但是我得到了这个错误日志: AttributeError: 'DateTimeProperty' 对象没有属性 'year'

我不知道为什么。我试过 Dates.date() == date, Dates.date == date (

我的数据库仍然是空的,但我想这并不介意,因为我永远不会有每个可能的日子的日期。

有人知道为什么吗?我应该改用 GQL 吗?

【问题讨论】:

    标签: google-app-engine datetime google-cloud-datastore app-engine-ndb


    【解决方案1】:

    您可以为此使用“范围”查询。请参阅下面的示例。

    import datetime
    date = datetime.datetime.strptime('02/19/2013', '%m/%d/%Y')
    kl = Dates.query(
        ndb.AND(Dates.date >= date),
                Dates.date < date + datetime.timedelta(days=1))
    

    将获取 02/19/2013 的所有日期时间。

    【讨论】:

    • 我自己测试了这个。一切正常。你确定你试过这个代码吗?如果你愿意,我可以提供一个完整的例子。
    • 完全搞糊涂了..我的错..你能编辑你的问题..这样我就可以收回我的反对票了吗?
    • 我尝试了您的解决方案并且错误已经消失,如果我继续使用 DateTimeProperty,我希望将来不会出现问题。我想我没有正确定义要比较的日期时间对象,strptime 方法有帮助。即使不使用范围也没有错误,只有 Dates.date==date
    • 操作!我确实需要使用“范围”从 00:00:00 到 24:00:00 偷看
    【解决方案2】:

    您想要实现的目标实际上是不可能的,因为您只能查询整个日期,而不能查询其中的某些部分。

    为了实现您在那里尝试的内容,我建议您向模型添加更多属性:

    class Dates(ndb.model):
        ...
        date = ndb.DateTimeProperty(requiered=True)
        date_year = ndb.IntegerProperty()
        date_month = ndb.IntegerProperty()
        date_day = ndb.IntegerProperty()
        ...
    

    您可以在每次保存时更新这些值,或者您可以使用 Model Hooks 自动执行此操作,然后您的新查询将变为:

    kl = Dates.query(ndb.AND(Dates.date_year == year,
                             Dates.date_month == month,
                             Dates.date_day == day),
                     ancestor=customer.key).fetch(keys_only=True)
    dates = ndb.get_multi(kl)
    

    【讨论】:

    • 哇!!我不想增加我的数据库大小。我想过在 date_max=date_at_23:59:59 和 date_min=date_at_00:00:00 之间进行查询。用于查询整个字段。但我得到了同样的错误。
    • @OscarParra 您不应该害怕添加更多字段,这不会减慢您的性能或会在付款方面产生任何(如果有的话)差异。通过这样做,您还可以按特定年份、月份等查询内容。通过简单地使用 DateTimeProperty,您将无法做到这一点。
    • @OscarParra 不要忘记你不能在同一个过滤器中使用多个不等式。从这里阅读限制:developers.google.com/appengine/docs/python/ndb/queries#intro
    • 谢谢,如果我必须对年、月、日、小时和分钟使用 IntegerProperty 来执行特定查询,那么我真的不需要 DateTimeProperty。这个属性真的这么没用吗?
    • @OscarParra 我不会说它没用,它在展示内容时非常有用,因为您可以直接使用 datetime 进行日期格式和其他内容,而其他字段对于过滤很有用。
    【解决方案3】:

    使用日期属性。然后你可以使用一个简单的 == 查询:

    >>> import datetime
    >>> from google.appengine.ext.ndb import *
    
    >>> class D(Model):
    ...   d = DateProperty()
    ...
    
    >>> d = D(d=datetime.date.today())
    
    >>> d.put()
    Key('D', 9)
    
    >>> d
    D(key=Key('D', 9), d=datetime.date(2013, 2, 20))
    
    >>> D.query(D.d == datetime.date.today()).fetch()
    [D(key=Key('D', 9), d=datetime.date(2013, 2, 20))]
    

    【讨论】:

    • 但是还有一个条件要保持时间。使用 '>' 和 '
    • 是的,我需要存储时间(我正在存储牙科诊所的日期,所以时间很重要)。德米特里解决方案工作正常。如果我不能对它执行复杂的查询,比如 p.e.获取星期一的所有日期?
    【解决方案4】:

    我扩展了@Guido van Rossum 代码 sn-p 以包括 和 timedelta 用于计算,主要是为了我自己的满意

    import datetime
    from datetime import timedelta
    
    from google.appengine.ext.ndb import *
    
    class D(Model):
      d = DateProperty()
    
    now = datetime.date.today()
    date1 =  now-timedelta(+500)
    date2 =  now-timedelta(+5)
    
    d1 = D(d=now)
    d2 = D(d=date1)
    d3 = D(d=date2)
    
    d1.put()
    d2.put()
    d3.put()
    
    date2 =  now-timedelta(+50)
    
    result1 = D.query(D.d == now).fetch(4)
    result2 = D.query(D.d > date2).fetch(2)
    result3 = D.query(D.d < date2).fetch(2)
    
    result4 = D.query(D.d >= date2, D.d <= now).fetch(2)
    
    print result1
    print "+++++++"
    print result2
    print "+++++++"
    print result3
    print "+++++++"
    print result4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多