Google App Engine (python): лучший способ определить, возвращает ли запрос результаты или нет

#python #google-app-engine

# #python #google-движок приложений

Вопрос:

Я использую фреймворк webapp в GAE, и чтобы показать результаты запроса, я выполняю get() для объекта запроса, а затем повторяю его, если get() возвращает что-либо, например:

 query = Employee.all().filter("some_boolean_property = ", True)
if query.get():
    for employee in query:
        # output employee.name etc.
        # ...
else:
    # output "no records found" message
    # ...
 

Причина, по которой я выполняю get(), а не просто выполняю else в цикле for, заключается в том, что я вывожу данные в таблицу, и я не хочу писать код таблицы, если результатов нет. Ранее вместо get() Я выполнял fetch(1), но я считаю, что они эквивалентны (т.е. get() просто выполняет запрос, но максимум с одним результатом). В этом заключается мой вопрос — правда ли, что я могу использовать get() таким образом, и это лучший способ узнать, возвращает ли запрос результаты или нет? Может ли count (1) быть лучше?

Меня не волнует количество результатов, просто есть ли они или нет.

Ответ №1:

Просто вызовите fetch , чтобы получить необходимое количество результатов, а затем выполните итерацию по ним. Например:

 query = Employee.all().filter("some_boolean_property = ", True)
results = query.fetch(20)
if results:
    for employee in results:
        # Do stuff
 

Комментарии:

1. Да, но я хочу повторить все результаты, поэтому, если я не дам fetch() аргумент, это будет еще один доступ к хранилищу данных. Если только я не использовал fetch(1), чтобы узнать, есть ли какие-либо данные (что было моим первоначальным вопросом, если fetch(1) или get () были хорошим способом сделать это или нет)

2. @fishwebby Должно быть практическое ограничение на количество результатов, которые вы хотите отобразить пользователям на одной странице. Страница с 1000, или 10 000, или 100 000 результатов на ней никому особенно не полезна.

3. Согласен, но пока Google не включит полнотекстовый поиск, я обманываю, загружая все результаты, затем используя datatable для разбиения на страницы и локального поиска на клиенте … по общему признанию, это будет работать только пока набор результатов невелик (что и есть на данный момент — надеюсь, Google сделает это в ближайшее время, хотя,но это уже другая тема 🙂

Ответ №2:

Альтернативой может быть установка флага внутри цикла, чтобы сообщить, что найдена хотя бы одна запись, а затем проверить этот флаг для вашего случая «не найдено записей».

 found = False
query = Employee.all().filter("some_boolean_property = ", True)
for employee in query:
    found = True
    # output employee.name etc.
    # ...
if not found:
    # output "no records found" message
    # ...
 

Преимущество этого заключается в удалении вызова хранилища данных.

Комментарии:

1. Мне это нравится — хотя это делает мой код немного более подробным, у него есть преимущество, как вы говорите, в удалении дополнительного вызова хранилища данных. Спасибо!

Ответ №3:

Вы можете использовать метод Query класса count . Если вы предоставите a limit , он проверит только это количество. Вот пример:

 query = Employee.all().filter("some_boolean_property = ", True)
if query.count(limit=1):
   for employee in query:
       pass
 

Комментарии:

1. Ах, хорошо — итак, как это можно сравнить с выполнением fetch(1) или get() в запросе?

2. Для этого все равно потребуется два RPC, когда требуется только один.

3. Он будет извлекать только количество, а не включать данные объекта в возвращаемый результат. Он выполнит два вызова RPC, но необходим в случае, когда вы будете выполнять только вторую выборку на основе результатов подсчета.

Ответ №4:

‘count’ возвращает только количество результатов, найденных с помощью запроса

‘get’ и ‘fetch’ возвращают всю сущность целиком

таким образом, «подсчет» намного эффективнее, если вам нужно только количество запросов

Также я не понимаю, почему люди запускают цикл после запроса для 1 элемента. Если вы используете get(), вы получите только 1 элемент, который соответствует, поэтому вам не нужен цикл. Все, что вы на самом деле проверяете, — это действительно ли вы получили объект или обратный отсчет из запроса.

Комментарии:

1. ОП хочет показать результаты в дополнение к информации о том, есть ли таковые.

2. @fishwebby — Если вам нужны все результаты, тогда вы должны получить столько, сколько сможете (я думаю, что 100 — это эмпирическое правило для GAE), вы считаете, что у вас будет больше, чем, я полагаю, вы используете смещение при выборке. Если результатов нет, вы получите «None» и просто протестируете с помощью оператора if, прежде чем переходить в цикл. Нет необходимости использовать count, если вы хотите возвращать объекты.