Management-команды¶
Запускаются через django-admin внутри контейнера:
docker compose run --rm web django-admin <команда> [аргументы]
или из shell контейнера (make shell) — ./manage.py <команда>.
Ниже — только команды портала. Штатные команды Django (migrate, createsuperuser,
collectstatic, makemigrations, shell) работают как обычно.
initialize¶
django-admin initialize
Загружает начальные фикстуры: типы антенн, режимы модуляции и прочие справочники.
Выполняется один раз при разворачивании новой базы. То же делает djangoctl.sh initialize.
fetch_data¶
django-admin fetch_data
Загружает спутники и передатчики из SatNOGS DB (DB_API_ENDPOINT). Ручной аналог
периодической задачи fetch_data, которая идёт раз в час.
update_station_last_seen¶
django-admin update_station_last_seen <station_id> [<station_id> ...]
Обновляет отметку последнего появления для перечисленных станций. Принимает один или несколько числовых идентификаторов. Нужна, когда станцию надо вернуть на связь руками, не дожидаясь очередного обращения её клиента.
recalculate_observation_ratings¶
django-admin recalculate_observation_ratings # предпросмотр
django-admin recalculate_observation_ratings --apply # запись
Сбрасывает завышенные оценки «good», записанные багом в ветке data_upload функции
rate_observation. По умолчанию — сухой прогон; запись только по --apply.
Команда намеренно консервативна: она трогает наблюдение, только если выполнены все
условия — статус 100, есть демодулированные данные, режим передачи вниз CW или FM, и
waterfall_status пуст (то есть водопад никто не вычитывал). Такие наблюдения
возвращаются в 0 («unknown»), а не в «bad».
Полное описание проблемы и рассуждение о том, почему нельзя откатить точнее, — в Оценка наблюдений.
confirm_satellite_reentries¶
django-admin confirm_satellite_reentries # предпросмотр
django-admin confirm_satellite_reentries --apply # запись
То же решение, что принимает суточная задача с тем же именем: перевод
подтверждённо сошедших аппаратов в статус re-entered с заполнением даты схода.
По умолчанию — сухой прогон; запись только по --apply, --limit N ограничивает
число аппаратов за прогон.
Предпросмотр печатает по строке на аппарат (номер NORAD, имя, сработавшее правило, дата, которая будет записана) и общее число будущих наблюдений этих спутников — команда их не трогает, решение снимать расписание остаётся за оператором.
Оба правила и порядок отката описаны в Спутники и передатчики.
release_precheck¶
django-admin release_precheck
Проверки данных перед обновлением портала — то, на чём упадут миграции релиза:
дубли NORAD в синтетическом диапазоне 70000–100000 (0039 ставит на него
уникальность), строки в таблицах входа через соцсети (0043 их удаляет и отказывается
при непустых), и число неприменённых миграций. Ничего не пишет; при находках печатает
их и завершается с ошибкой. Запускать до кнопки выкатки образом новой версии на базе
прода:
docker run --rm --env-file .env --network <сеть compose> <образ новой версии> django-admin release_precheck
Что делать с находками — в CHANGELOG, раздел «Требует действий».
dump_satellite_descriptions¶
django-admin dump_satellite_descriptions > descriptions.json
django-admin dump_satellite_descriptions --limit 50 > batch.json
Выгружает описания спутников в JSON — исходящая половина обмена для перевода. Портал не подключает сервисов перевода: текст переводится снаружи и возвращается тем же файлом.
Отдаются те аппараты, у которых хотя бы одна из шести языковых колонок
заполнена и хотя бы одна пуста, то есть ровно те, где есть с чего переводить и
куда. Полностью пустой аппарат — не задача на перевод, полностью заполненный уже
готов. --limit N режет выдачу для перевода порциями.
В stdout идёт только JSON и ничего больше, поэтому вывод можно перенаправлять в файл.
load_satellite_descriptions¶
django-admin load_satellite_descriptions descriptions.json # предпросмотр
django-admin load_satellite_descriptions descriptions.json --apply # запись
django-admin load_satellite_descriptions - # из stdin
Загружает переведённый JSON обратно. По умолчанию — сухой прогон; запись только по
--apply.
Два правила решают, что будет записано:
поле, названное в
locked_fieldsэтого спутника, не трогается никогда — в этом и состоит смысл блокировки (см. Спутники и передатчики);значение, совпадающее с уже записанным, записью не считается.
Отсюда идемпотентность: повторный прогон того же файла ничего не меняет, а выгрузка,
пропущенная обратно через эту команду, — пустая операция. Спутник с неизвестным
sat_id считается и пропускается, а не роняет загрузку: каталог живёт, и партия
перевода недельной давности не должна падать целиком из-за одного слитого аппарата.
Отчёт печатает, сколько записано, сколько полей пропущено по блокировке и сколько аппаратов не нашлось в каталоге.
backfill_analytics¶
django-admin backfill_analytics [--force] [--since YYYY-MM-DD]
Считает суточные метрики аналитики за все прошедшие дни начиная с даты создания самой
старой станции. Ставит задачу backfill_historical_metrics в очередь Celery и сразу
возвращает управление — результата в выводе команды не будет, смотреть логи воркера.
Аргумент |
Назначение |
|---|---|
|
Пересчитать дни, для которых метрики уже есть. Нужен после добавления новых полей метрик — иначе существующие строки останутся со значениями по умолчанию |
|
Дата начала в формате |
Подробнее — Аналитика.
copy_demoddata_content¶
django-admin copy_demoddata_content [--workers N]
Копирует файлы кадров и их payload_json из хранилища в таблицу DemodDataContent,
откуда их отдаёт /api/demoddata/. Пока у кадра нет копии, API читает его файл,
то есть делает GET в S3 на каждую строку страницы. Новые кадры получают копию сами
(в задаче decode_current_frame), поэтому команда нужна один раз, для кадров,
принятых до её появления.
Идёт от новых кадров к старым пачками по 1000: файлы пачки читают --workers
потоков (по умолчанию 32), а в базу пачка пишется одним INSERT. Кадр, у которого
уже есть копия, не трогается. Поэтому прерванный прогон можно запустить снова, и он
продолжит с того места, где остановился. Кадр, файл которого не читается,
записывается в лог и пропускается: API продолжает читать его из файла, как раньше.
Каждая пачка печатает прогресс: сколько скопировано и пропущено, последний id и
скорость в кадрах в секунду. Для оценки места под базу остановите команду на первых
~100 тыс. кадрах и разделите pg_total_relation_size('base_demoddatacontent') на
число строк в таблице.