Почему мой запрос GQL не возвращает никаких результатов в моем приложении GAE?

В основном я следовал руководству о том, как создать гостевую книгу с помощью GAE и Python. Теперь я хочу показать записи только за определенный день, но запрос GQL ничего не возвращает (хотя записи за этот день есть):

class Shout(db.Model):  
    message= db.StringProperty(required=True)  
    when = db.DateTimeProperty(auto_now_add=True)  
    who = db.StringProperty()  

class MainHandler(webapp.RequestHandler):  
    def get(self):  
        shouts = db.GqlQuery("SELECT * FROM Shout WHERE when=DATE('2010-11-05')")  
        # Return something without the WHERE clause
        values = {'shouts':shouts}  
        self.response.out.write(template.render('main.html',values))  

    def post(self):  
        self.response.out.write("posted")  
        shout = Shout(message=self.request.get("message"),who=self.request.get("who"))  
        shout.put()  

Это мой main.html:

<form method="post">
   <input type="text" name="who"></input>
   <input type="text" name="message"></input>
   <input type="submit" value="Send"> </input>  
</form>

{% for shout in shouts  %}
   <div>{{shout.message}} from {{shout.who}} on {{shout.when}}</div>
{% endfor %}

person weiqure    schedule 05.11.2010    source источник


Ответы (2)


Может быть и другой способ обойти это, но я думаю, что, поскольку ваше свойство when является датой и временем, вам лучше было бы использовать что-то вроде этого:

shouts = db.GqlQuery("""SELECT * 
                          FROM Shout 
                         WHERE when >= DATE('2010-11-05')
                           AND when < DATE('2010-11-06')""")
person mechanical_meat    schedule 05.11.2010
comment
+1. Кроме того, вы можете добавить DateProperty в свою модель, а затем запросить ее с помощью фильтра равенства. Это заняло бы немного больше места, но было бы проще запрашивать (равенство по сравнению с двумя реляционными операторами - особенно важно, поскольку вы можете использовать реляционный оператор только в одном поле). - person David Underhill; 05.11.2010
comment
Спасибо, что добавил это, Дэвид. - person mechanical_meat; 05.11.2010
comment
Спасибо, теперь работает. Это из-за какой-то проблемы с округлением я не могу просто использовать '='? - person weiqure; 05.11.2010
comment
Я попытался заставить = работать с некоторыми примерами данных. Это кажется невозможным, потому что свойства DateTime хранятся в микросекундах; которые AFAICT не поддерживаются в GQL. - person mechanical_meat; 05.11.2010
comment
@user67011 user67011 Это потому, что время публикации сохраняется как дата-время (это то, что вы указали), а ваша дата переводится в полночь того дня как дата-время. Ваш запрос вернет только результаты, опубликованные ровно в полночь, потому что это единственные результаты, опубликованные точно в это время. - person Nick Johnson; 07.11.2010

Попробуй это:

shouts = db.GqlQuery("SELECT * FROM Shout WHERE when=DATE('2010-11-05')").fetch(5000)

Хотя можно использовать объект Query в качестве итерируемого объекта, лучше явно извлекать строки и не зависеть от for в вашем шаблоне для выполнения работы. Я подозреваю, что это не поддерживается таким образом.

РЕДАКТИРОВАТЬ: теперь, когда я более внимательно смотрю на это, я подозреваю, что проблема в том, что поле, которое вы запрашиваете, является DateTimeProperty, и с помощью оператора DATE вы, по сути, говорите, что хотите 2010-11-05 00:00 :00, и нет записей с точной датой и временем, поэтому попробуйте вместо этого:

shouts = db.GqlQuery("SELECT * FROM Shout WHERE when >= DATETIME('2010-11-05 00:00:00') and when <= DATETIME('2010-11-05 23:59:59')")
person Adam Crossland    schedule 05.11.2010
comment
Та же проблема, что и раньше. Я полагаю, что выборка не нужна, потому что она не используется в примерах приложений (например, code.google.com/p/google-app-engine-samples/source/browse/trunk/). - person weiqure; 05.11.2010
comment
Я согласен с тем, что лучше извлекать строки явно — более эффективно извлекать их все сразу (итератор извлекает их фрагментами, что приводит к дополнительным обращениям к хранилищу данных). Тем не менее, нет проблем с повторением шаблона по объекту запроса — он работает так же, как если бы вы перебирали его с помощью обычного цикла for. - person David Underhill; 05.11.2010
comment
Я не пытаюсь звучать обвинительно: мне не нравится видеть отрицательные голоса, когда кто-то явно пытается быть полезным. Спасибо за ответ, Адам. - person mechanical_meat; 05.11.2010
comment
Ну что ж. Я бросился отвечать на вопрос и не подумал. Виноват. - person Adam Crossland; 05.11.2010