Django команда управления не работает sh stdout - PullRequest
5 голосов
/ 26 мая 2020

Я пытаюсь распечатать на консоли до и после обработки, которая занимает некоторое время в команде управления Django, например:

import requests
import xmltodict

from django.core.management.base import BaseCommand


def get_all_routes():
    url = 'http://busopen.jeju.go.kr/OpenAPI/service/bis/Bus'

    r = requests.get(url)
    data = xmltodict.parse(r.content)

    return data['response']['body']['items']['item']


class Command(BaseCommand):

    help = 'Updates the database via Bus Info API'

    def handle(self, *args, **options):
        self.stdout.write('Saving routes ... ', ending='')
        for route in get_all_routes():
            route_obj = Route(
                route_type=route['routeTp'], route_id=route['routeId'], route_number=route['routeNum'])
            route_obj.save()
        self.stdout.write('done.')

В приведенном выше коде ожидается, что Saving routes ... print перед начинается l oop, и done. сразу рядом с ним, когда l oop завершается, так что в конце он выглядит как Saving routes ... done..

Однако, первый не печатается до тех пор, пока l oop не завершится, когда обе строки, наконец, будут напечатаны одновременно, чего я не ожидал.

Я нашел этот вопрос , где Ответ предлагает очистить вывод, т.е. self.stdout.flush(), поэтому я добавил это в свой код:

    def handle(self, *args, **options):
        self.stdout.write('Saving routes ... ', ending='')
        self.stdout.flush()
        for route in get_all_routes():
            route_obj = Route(
                route_type=route['routeTp'], route_id=route['routeId'], route_number=route['routeNum'])
            route_obj.save()
        self.stdout.write('done.')

Тем не менее, результат остается неизменным.

Что я мог сделать не так?

Ответы [ 2 ]

5 голосов
/ 30 мая 2020

Следует иметь в виду, что вы используете self.stdout (как предлагается в Django документах), который является заменой BaseCommand стандартного sys.stdout Python. Есть два основных различия между двумя, имеющими отношение к вашей проблеме:

  1. По умолчанию "окончание" в версии self.stdout.write () BaseCommand - это новая строка, заставляющая вас использовать end = '' параметр, в отличие от sys.stdout.write (), который имеет пустое окончание по умолчанию. Это само по себе не вызывает вашей проблемы.
  2. Версия flu sh () BaseCommand на самом деле ничего не делает (кто бы мог подумать?). Это известная ошибка: https://code.djangoproject.com/ticket/29533

Итак, у вас действительно есть 2 варианта:

  1. Не использовать BaseCommand self.stdout, а использовать sys .stdout, и в этом случае flu sh действительно работает
  2. Заставить стандартный вывод быть полностью небуферизованным при выполнении команды управления, передав параметр «-u» в python. Поэтому вместо запуска python manage.py <subcommand> запустите python -u manage.py <subcommand>

Надеюсь, это поможет.

0 голосов
/ 02 июня 2020

Вы пытались установить переменную окружения PYTHONUNBUFFERED ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...