Документация 0.4 Отчёты
SQL-запросы
«Отчёты» → «Запросы» — SQL-запросы к базе отчётов: свои сводки и графики по копии заданий, элементов очередей и по пользовательским отчётам. Писать и сохранять запросы могут разработчики, владелец области и аудитор; сохранённые общие запросы выполняют все, кто видит отчёты области.

Как устроено #
У каждой рабочей области в базе отчётов своя схема. В ней:
- копия данных оркестратора — таблицы
jobs,queue_items,processes,robots,queuesи представленияprocess_daily,robot_daily. Сервер обновляет копию каждые 5 минут, поэтому самые свежие задания появляются в запросах с задержкой до 5 минут. Аргументы и результат заданий, тексты ошибок, данные (payload) и результат элементов очередей в копию не копируются; - таблицы пользовательских отчётов —
r_<ключ отчёта>, напримерr_paymentsдля отчёта „Платежи“.
Запрос выполняется от роли рабочей области: он видит только свою схему и не видит основную базу оркестратора и схемы других областей.
Схема #
Справа в редакторе — «Схема» со всеми таблицами и колонками области; щелчок вставляет имя в запрос. Время во всех
таблицах — timestamptz; дни в process_daily и robot_daily — по часовому поясу организации.
jobs — задания #
| Колонка | Тип | Что это |
|---|---|---|
id |
uuid |
Идентификатор задания (с ним соединяются queue_items.job_id и r_*._job_id) |
number |
bigint |
Номер задания, как в панели |
process_id, process |
uuid, text |
Процесс и его имя |
version |
text |
Версия процесса |
robot_id, robot |
uuid, text |
Робот и его имя (пусто, если робот не назначался) |
source |
text |
manual, schedule, queue, api, attended, studio, retry, selftest |
status |
text |
pending, assigned, running, stopping, succeeded, failed, cancelled, lost |
priority |
text |
high, normal, low |
error_code |
text |
Код ошибки (ElementNotFound, JobTimeout …) |
attempt |
int |
Попытка (у повторов больше 1) |
trigger_id, retry_of_job_id |
uuid |
Расписание, создавшее задание; задание, которое повторяет этот запуск |
created_at, assigned_at, started_at, finished_at |
timestamptz |
Создано, назначено роботу, начато, завершено |
duration_ms |
bigint |
Длительность от начала работы до завершения, мс |
run_duration_ms |
bigint |
Время выполнения процесса на роботе, мс |
updated_at |
timestamptz |
Последнее изменение |
queue_items — элементы очередей #
| Колонка | Тип | Что это |
|---|---|---|
id, queue_id, queue |
uuid, uuid, text |
Элемент, очередь и её имя |
reference |
text |
Ссылка элемента (номер заявки) |
priority |
text |
high, normal, low |
status |
text |
new, inProgress, succeeded, failed, abandoned, deleted (ждущие повтора и отложенные — new) |
attempt |
int |
Номер попытки |
error_type |
text |
business или system |
resolved_manually |
boolean |
Завершён оператором вручную |
created_at, started_at, finished_at, deadline |
timestamptz |
Добавлен, взят в работу, обработан, срок |
job_id, robot |
uuid, text |
Задание и робот, которые обработали элемент |
updated_at |
timestamptz |
Последнее изменение |
process_daily и robot_daily — итоги по дням #
| Представление | Колонки |
|---|---|
process_daily |
day (date), process_id, process, runs, succeeded, failed, cancelled, avg_duration_ms (средняя длительность успешных) |
robot_daily |
day (date), robot_id, robot, jobs, succeeded, failed, busy_ms (сумма run_duration_ms) |
Дни считаются по jobs.created_at в часовом поясе организации.
Справочники #
| Таблица | Колонки |
|---|---|
processes |
id, name, is_enabled, archived |
robots |
id, name, mode (unattended / attended), is_enabled, licensed |
queues |
id, name |
r_<ключ> — пользовательские отчёты #
Колонки полей называются ключами полей (number, amount, paid_on, status), типы — как в
определении отчёта: текст и список — text, целое — bigint, число с дробью — numeric, дата —
date, дата и время — timestamptz, да/нет — boolean, JSON — jsonb. Скрытые поля остаются колонками. Системные
колонки каждой таблицы:
| Колонка | Что это |
|---|---|
_id |
Идентификатор записи |
_created_at, _updated_at |
Когда записано и изменено |
_source |
robot, operator, import |
_job_id, _job_number |
Задание, которое записало (соединение с jobs.id), и его номер |
_process, _process_version, _robot |
Процесс, версия и робот |
_queue_item_ref |
Ссылка элемента очереди, который задание обрабатывало |
Параметры #
Пишите :имя прямо в тексте: WHERE day BETWEEN :from AND :to. Под редактором появятся «Параметры»: «Подпись»,
«Тип» («Текст», «Целое», «Число», «Дата», «Дата и время», «Да / нет») и «По умолчанию». У :from, :to и :process
подписи готовые. Значения передаются серверу отдельно от текста — подставить в запрос чужой SQL через параметр
нельзя. Если PostgreSQL не может понять тип параметра, приведите его: :from::date.
Относительные даты. Значением параметра «Дата» или «Дата и время» может быть слово — оно считается в часовом поясе организации в момент выполнения:
| Значение | Что подставится |
|---|---|
today, yesterday, tomorrow |
Сегодня, вчера, завтра |
today-7, today+1 |
Сдвиг на N дней |
startOfWeek, startOfPrevWeek |
Понедельник этой и прошлой недели |
startOfMonth, startOfPrevMonth |
Первое число этого и прошлого месяца |
startOfYear, startOfPrevYear |
1 января этого и прошлого года |
now |
Текущий момент |
Для «Дата» подставляется день, для «Дата и время» — полночь этого дня (now — сам момент). Пример „за вчера“:
WHERE _created_at >= :from AND _created_at < :to со значениями from = yesterday, to = today. В панели те же
значения выбираются из списка: „вчера“, „начало месяца“ и т. д.
Ограничения #
| Что | Ограничение |
|---|---|
| Текст запроса | Один оператор SELECT или WITH; изменить данные нельзя — транзакция только для чтения |
| Время выполнения | 60 с; выгрузка — до 600 с |
| Строк на экране | Первые 1 000 (все строки — в выгрузке CSV или Excel) |
| Выгрузка | CSV — без ограничения строк, Excel — до 1 048 575 строк |
| Одновременно | Не больше 2 запросов на пользователя и 8 на сервер — иначе „Слишком много запросов“, повторите через минуту |
Ошибка PostgreSQL показывается со строкой и столбцом — «Показать в тексте» подсветит место. «План» показывает
EXPLAIN без выполнения запроса.
Сохранить запрос и график #
«Сохранить» → «Название», «Описание», «Доступ»: «Вся область» (общий запрос — выполняют все, кто видит отчёты области, меняют те, кому можно писать SQL) или «Только я». Параметры с подписями и значениями по умолчанию сохраняются вместе с запросом.
График. На вкладке «График» результата выберите «Вид» — «Столбцы», «Линия», «Площадь» или «Круговая», «Ось X» и «Значения» (до 8 числовых колонок; у круговой — первая колонка, до 8 долей). График сохраняется вместе с запросом.
Сохранённый запрос открывается на своей странице: значения параметров, таблица, график и выгрузка. Его же можно
рассылать по расписанию, проверять правилом и
загружать в очередь. Через API — POST /api/v1/reports/queries/{id}/run и
/export (см. ниже).
Из Power BI и Excel #
Результаты запросов можно забирать в BI-системы двумя способами.
Через API #
POST /api/v1/reports/sql/run (свой SQL), POST /api/v1/reports/sql/export (выгрузка CSV или Excel), POST /api/v1/reports/queries/{id}/run и /export (сохранённый запрос с параметрами). Хватает токена «Только чтение»:
запросы только читают. Права — как у владельца токена: свой SQL — разработчик, владелец области, аудитор,
администратор; сохранённый общий запрос — все, кто видит отчёты области. Примеры — в API.
В Power BI это „Получить данные“ → „Веб“ с заголовком Authorization: Bearer tlp_…; проще всего выгрузка csv
сохранённого запроса.
Прямое подключение BI #
Power BI, Excel и другие BI-системы подключаются к базе отчётов напрямую через коннектор PostgreSQL ролью своей рабочей области:
- Администратор открывает «Настройки» → «Отчёты»: «Сервер», «Порт», «База данных» и в таблице «Роли рабочих областей» — «Роль (логин)» нужной области. «Показать пароль» показывает пароль один раз, «Скопировать пароль» — в буфер обмена; каждый показ записывается в аудит.
- В Power BI — „Получить данные“ → „База данных PostgreSQL“: сервер (
адрес:порт), база данных, затем „База данных“ → имя роли и пароль. В Excel — „Данные“ → „Получить данные“ → „Из базы данных“ → „Из базы данных PostgreSQL“. - Таблицы и представления — те же, что в схеме, в схеме
ws_<идентификатор области>; она же схема по умолчанию для роли.
Роль только читает (default_transaction_read_only) и видит только схему своей области; запрос длиннее 60 с
прерывается (statement_timeout), одновременно — не больше 4 подключений вместе с сервером. Подробности для
администратора (сетевой доступ к PostgreSQL, смена пароля) — в Базе отчётов.
Примеры запросов #
Все примеры выполняются на схеме области как есть. Таблица r_payments — отчёт „Платежи“ (поля number, amount,
paid_on, status), как в образце samples/orchestrator/08_report_writer.
1. Успешность процессов за период — :from, :to типа «Дата»; график «Столбцы» по process.
SELECT process,
sum(runs) AS runs,
sum(succeeded) AS succeeded,
sum(failed) AS failed,
round(100.0 * sum(succeeded) / nullif(sum(runs) - sum(cancelled), 0), 1) AS success_pct
FROM process_daily
WHERE day BETWEEN :from AND :to
GROUP BY process
ORDER BY runs DESC
2. Неуспешные платежи за вчера — :from = yesterday, :to = today типа «Дата и время».
SELECT number, amount, paid_on, _robot AS robot, _job_number AS job
FROM r_payments
WHERE status = 'Ошибка'
AND _created_at >= :from AND _created_at < :to
ORDER BY amount DESC NULLS LAST
3. Сумма платежей по дням — :from = startOfMonth; график «Линия», ось X — day, значения — paid, failed.
SELECT (_created_at AT TIME ZONE 'Asia/Bishkek')::date AS day,
coalesce(sum(amount) FILTER (WHERE status = 'Оплачен'), 0) AS paid,
coalesce(sum(amount) FILTER (WHERE status = 'Ошибка'), 0) AS failed
FROM r_payments
WHERE _created_at >= :from
GROUP BY 1
ORDER BY 1
4. Платежи по роботам и время заданий — соединение отчёта с заданиями по _job_id.
SELECT j.robot,
count(*) AS payments,
sum(p.amount) AS total,
round(avg(j.run_duration_ms) / 1000.0, 1) AS avg_job_s
FROM r_payments p
JOIN jobs j ON j.id = p._job_id
WHERE j.created_at >= :from AND j.created_at < :to
GROUP BY j.robot
ORDER BY payments DESC
5. Коды ошибок заданий за 7 дней и их доля — без параметров; график «Круговая».
SELECT coalesce(error_code, 'без кода') AS error_code,
count(*) AS jobs,
round(100.0 * count(*) / sum(count(*)) OVER (), 1) AS share_pct
FROM jobs
WHERE status IN ('failed', 'lost')
AND created_at >= now() - interval '7 days'
GROUP BY 1
ORDER BY jobs DESC
LIMIT 10
6. Элементы очередей в срок и позже срока
SELECT queue,
count(*) AS finished,
count(*) FILTER (WHERE finished_at > deadline) AS late,
round(100.0 * count(*) FILTER (WHERE finished_at <= deadline)
/ nullif(count(deadline), 0), 1) AS in_time_pct
FROM queue_items
WHERE status IN ('succeeded', 'failed', 'abandoned')
AND finished_at >= :from AND finished_at < :to
GROUP BY queue
ORDER BY late DESC
7. Часы работы роботов по дням и режимам — график «Площадь».
SELECT d.day,
r.mode,
sum(d.jobs) AS jobs,
round(sum(d.busy_ms) / 3600000.0, 1) AS busy_hours
FROM robot_daily d
JOIN robots r ON r.id = d.robot_id
WHERE d.day BETWEEN :from AND :to
GROUP BY d.day, r.mode
ORDER BY d.day, r.mode
8. Включённые процессы, которые не запускались 7 дней
SELECT p.name
FROM processes p
WHERE p.is_enabled AND NOT p.archived
AND NOT EXISTS (SELECT 1 FROM jobs j
WHERE j.process_id = p.id AND j.created_at >= now() - interval '7 days')
ORDER BY p.name
9. Сколько запусков спасли автоповторы
SELECT process,
count(*) FILTER (WHERE source = 'retry' AND status = 'succeeded') AS ok_after_retry,
count(*) FILTER (WHERE source = 'retry') AS retries
FROM jobs
WHERE created_at >= :from
GROUP BY process
ORDER BY ok_after_retry DESC
10. Дубликаты номера платежа — запрос для проверки качества данных: правильный результат — ни одной строки.
SELECT number, count(*) AS records
FROM r_payments
GROUP BY number
HAVING count(*) > 1