@Sabrjkee

Как в django брать записи из модели друг за другом не исполюзуя .all()?

Мне нужно создать функцию, которая будет запускаться в celery и по очереди получать записи из модели, что-то проверять и записывать данные в другую модель с onetoone отношением. Записей очень много, и использование model_name.objects.all () и потом итерировать по нему, не подойдет (это займет много памяти и времени), как это можно сделать.
  • Вопрос задан
  • 402 просмотра
Решения вопроса 1
fox_12
@fox_12 Куратор тега Django
Расставляю биты, управляю заряженными частицами
Добавьте к первой модели булевое поле, типа is_processed
Делайте выборку по нему .filter(is_processed=False), получая порцию данных, к примеру .first() или делая срез, и устанавливая флаг после обработки у обработанных инстансов.
Повторяете предыдущий шаг, пока не выставите все флаги.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@deliro
Есть .iterator(), но его использование (почти) бесполезно без использования server-side cursors.

Поэтому проще получать срезы. Если есть гарантия, что записи за время работы задачи не создаются, то это просто срезы: Model.objects.all()[0:200], Model.objects.all()[200:400], ...

Если гарантии нет, то нужно придумать фильтрацию. Например:

Первая выборка — Model.objects.order_by("-id")[:200]
Вторая и все следующие —
Model.objects.filter(id__lt=<последний id из предыдущей выборки>).order_by("-id")[:200]
Ответ написан
одна задача в celery бежит по всем записям и если необходимо создает много маленьких задач в том же celery
тоесть Ваша задача просто превращается в задачу-диспетчер, а вся логика для конкретной записи укладывается в этой маленькой задаче. желательно эти маленьки задача выделить в отдельный воркер, с большим значением concurensy
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы