подсистема Google App Engine подсчитывает количество записей из модели NDB - PullRequest
0 голосов
/ 23 октября 2018

Сколько записей мы можем получить из Google App Engine из одного запроса, чтобы мы могли отобразить счетчик для пользователя и увеличить лимит времени ожидания с 3 до 5 секунд

1 Ответ

0 голосов
/ 23 октября 2018

По моему опыту, ndb не может извлекать более 1000 записей одновременно.Вот пример того, что произойдет, если я попытаюсь использовать .count() для таблицы, содержащей ~ 500 000 записей.

s~project-id> models.Transaction.query().count()
WARNING:root:suspended generator _count_async(query.py:1330) raised AssertionError()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/utils.py", line 160, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/query.py", line 1287, in count
    return self.count_async(limit, **q_options).get_result()
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/tasklets.py", line 383, in get_result
    self.check_success()
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/tasklets.py", line 427, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/query.py", line 1330, in _count_async
    batch = yield rpc
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/ndb/tasklets.py", line 513, in _on_rpc_completion
    result = rpc.get_result()
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 614, in get_result
    return self.__get_result_hook(self)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/datastore/datastore_query.py", line 2910, in __query_result_hook
    self._batch_shared.conn.check_rpc_success(rpc)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1377, in check_rpc_success
    rpc.check_success()
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 580, in check_success
    self.__rpc.CheckSuccess()
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_rpc.py", line 157, in _WaitImpl
    self.request, self.response)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 308, in MakeSyncCall
    handler(request, response)
  File "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/platform/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 362, in _Dynamic_Next
    assert next_request.offset() == 0
AssertionError

Чтобы обойти это, вы можете сделать что-то вроде:

objs = []
q = None
more = True
while more:
    _objs, q, more = models.Transaction.query().fetch_page(300, start_cursor=q)
    objs.extend(_objs)

Но даже это в конечном итоге приведет к ограничению памяти / тайм-аута.

В настоящее время я использую Google Dataflow для предварительного вычисления этих значений и сохраняю результаты в Datastore как модели DaySummaries & StatsPerUser

РЕДАКТИРОВАТЬ:

snakecharmerb правильно.Я смог использовать .count() в производственной среде, но чем больше сущностей он должен считать, тем дольше он кажется.Вот скриншот моего средства просмотра журналов, где для подсчета ~ 330 000 записей потребовалось ~ 15 секунд

enter image description here

Когда я попытался добавить фильтр к этому запросу, который возвратилсчетчик ~ 4500, вместо этого потребовалось около секунды.

РЕДАКТИРОВАТЬ # 2:

Хорошо, у меня был еще один проект движка приложения с видом ~ 8 000 000 записей.Я попытался сделать .count() для этого в моем http-обработчике запросов и тайм-аут запроса после выполнения в течение 60 секунд.

enter image description here

...