9

Ich habe ein Problem, und ich finde keine Informationen über.Ndb Query-Fehler mit Datetime-Feld - Google App Engine

Ich definiere ein Feld in meinem Modell wie folgt.

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

Später versuche ich, eine Abfrage (jetzt will ich alle Termine für einen Tag, ich don'tn die Zeit dagegen):

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) 

Aber ich bekomme diese Fehlerprotokoll: Attribute: ' DateTimeProperty 'Objekt hat kein Attribut' Jahr '

Ich weiß nicht warum. Ich habe versucht, Dates.date() == Datum, Dates.date == Datum (< -DateTime Obj), ...

Meine DB ist immer noch leer, aber ich nehme an, dass dies nichts dagegen hat, weil ich werde nie Daten für alle möglichen Tage haben.

Jeder weiß warum? Soll ich stattdessen mit GQL gehen?

Antwort

16

Sie können „Bereich“ Anfragen für diese. Siehe Beispiel unten.

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)) 

Wird alle Datetime mit 02/19/2013 abrufen.

+0

Sie können das nicht tun .. überprüfen Sie die Einschränkungen .. https://developers.google.com/appengine/docs/python/ndb/queries#intro – Lipis

+2

Ich habe das selbst getestet. Funktioniert alles. Bist du sicher, dass du diesen Code ausprobiert hast? Ich kann ein komplettes Beispiel liefern, wenn Sie möchten. –

+0

Völlig verwirrt es .. meine schlechte .. können Sie Ihre Frage bearbeiten .. so kann ich meinen Downvote zurückziehen? – Lipis

7

Was Sie erreichen möchten, ist nicht wirklich möglich, da Sie nur das gesamte Datum und nicht einige Teile davon abfragen können.

Um zu erreichen, was Sie versuchen, dort würde ich vorschlagen, Sie zu Ihrem Modell einige Eigenschaften hinzuzufügen:

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

Sie diese Werte aktualisieren könnte auf jedem Speichern oder Sie könnten Model Hooks verwenden Sie es automatisch zu tun und dann neue Abfrage werden:

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) 
+0

Wow !! Ich möchte meine Datenbankgröße nicht erhöhen. Ich habe gedacht, dass etwas zwischen einem date_max = date_at_23: 59: 59 und date_min = date_at_00: 00: 00 abfragen kann. Zur Abfrage mit dem gesamten Feld. Aber ich bekomme die gleiche Fehlerklasse. –

+0

@OscarParra Sie sollten keine Angst haben, weitere Felder hinzuzufügen, dies wird Ihre Leistung nicht verlangsamen oder irgendwelche (wenn überhaupt) Unterschiede in den Zahlungen haben. Auf diese Weise können Sie auch nach bestimmten Jahren, Monaten usw. abfragen. Etwas, das Sie sonst nicht tun können, indem Sie einfach DateTimeProperty verwenden. – Lipis

+0

@OscarParra Vergessen Sie nicht, dass Sie nicht mehrere Ungleichungen im selben Filter verwenden dürfen. Lesen Sie die Einschränkungen hier: https://developers.google.com/appengine/docs/python/ndb/queries#intro – Lipis

2

Verwenden Sie eine DateProperty. Dann können Sie eine einfache == Abfrage verwenden:

>>> 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))] 
+0

Aber es gab eine Bedingung, um auch eine Zeit zu behalten. Lösung mit den Operatoren '>' und '<' wird viel mehr Ressourcen verwenden? Ich benutze diesen "Trick" sogar, um Schlüssel nach Anfangsbuchstaben zu filtern. –

+0

Ja, ich muss die Zeit speichern (ich speichere Termine für Zahnkliniken, also ist Zeit wichtig). Dmitry Lösung funktioniert gut. Was sind die Vorteile der Verwendung von DateTimeProperty über einige IntegerProperties, wenn ich keine komplexen Abfragen darüber ausführen kann, wie z. bekomme alle Termine am Montag? –

1

I @Guido van Rossum Code-Schnipsel erweitert, um <> und Timedelta für Berechnungen, vor allem für meine eigene Zufriedenheit

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