Импорт и экспорт отчётов, и наборов данных через API - Публичная база знаний Modus
Общее описание
Начиная с версии 3.14.21 в Modus BI реализован механизм переноса объектов между аналитическими порталами через API. Команды transfer.export и transfer.import позволяют экспортировать отчёты, наборы данных, источники данных и группы отчётов в пакет (Package) и импортировать его на другой портал.
Ключевые особенности:
- Объекты переносятся с сохранением их ID (в отличие от старого импорта отчётов, где создавался новый объект);
- При импорте: если объекта с таким ID нет — он создаётся, если есть — обновляется. Лишние объекты не удаляются;
- Атомарность импорта: либо переносятся все объекты из пакета, либо ничего. При любой ошибке выполняется откат;
- Требуется маппинг источников данных (связывание ID источника в пакете с ID источника на целевом портале).
Права доступа:
- Требуется авторизация;
- Доступно ролям:
- Администратор;
- Разработчик.
Экспорт объектов. Перенос между порталами (transfer.export)
Команда создаёт пакет (Package) с отчётами, группами отчётов, наборами данных и источниками данных для переноса на другой портал. Объекты экспортируются с сохранением их ID — при импорте они будут перенесены с теми же идентификаторами. Включает все связанные данные: трансформации, шаблоны экспорта (XLSX/PPTX), изображения.
Права доступа:
- Требуется авторизация;
- Доступна ролям: администратор, разработчик.
Спецификации:
-
URL: https://
/v1/ api/transfer — где — адрес вашего экземпляра Modus BI. - Тип запроса:
POST - Тип данных запроса:
JSON
Параметры запроса
В разделе рассмотрено тело запроса команды transfer.export. Параметры представлены в порядке: Параметр (key), Тип, Описание, Примечание.
| Параметр (key) | Тип данных | Описание | Примечание |
|---|---|---|---|
$.object.name |
Строка | Имя объекта: "transfer" |
Обязательный параметр |
$.command.name |
Строка | Имя команды: "export" |
Обязательный параметр |
$.data[0].report_ids |
Массив из Число | ID отчётов для экспорта | |
$.data[0].dataset_ids |
Массив из Число | ID наборов данных | |
$.data[0].report_group_ids |
Массив из Число | ID групп отчётов (включая родителей) |
Ограничение: хотя бы один из массивов report_ids, dataset_ids, report_group_ids должен быть непустым.
Параметры ответа
В разделе рассмотрено тело ответа. Параметры представлены в порядке: Параметр (key), Тип данных, Описание.
$.mode- Строка - Состояние сервиса портала$.status- Число - Статус выполнения. 200 - команда выполнена, иное значение - возникла ошибка$.message- Строка - Описание ошибки выполнения команды$.data[0]- Объект - Пакет с экспортированными данными:$.data[0].version- Строка - Версия портала, создавшего пакет$.data[0].exported_at- Строка - Дата и время экспорта (ISO 8601)$.data[0].datasources- Массив из Объект - Источники данных (без паролей):$.data[0].datasources[*].datasource_id- Число - Идентификатор источника данных$.data[0].datasources[*].driver_id- Число - Идентификатор драйвера$.data[0].datasources[*].name- Строка - Имя источника данных$.data[0].datasources[*].caption- Строка - Заголовок источника данных$.data[0].datasources[*].host- Строка - Хост$.data[0].datasources[*].port- Число - Порт$.data[0].datasources[*].base- Строка - Имя базы данных$.data[0].datasources[*].schema- Строка - Схема БД
$.data[0].datasets- Массив из Объект - Наборы данных:$.data[0].datasets[*].dataset_id- Число - Идентификатор набора данных$.data[0].datasets[*].datasource_id- Число - Идентификатор источника данных$.data[0].datasets[*].name- Строка - Имя набора данных$.data[0].datasets[*].caption- Строка - Заголовок набора данных$.data[0].datasets[*].query- Строка - SQL-запрос$.data[0].datasets[*].query_rls- Строка - SQL-запрос RLS$.data[0].datasets[*].limit- Число - Лимит количества записей$.data[0].datasets[*].cached- Число - Признак кэширования (0/1)$.data[0].datasets[*].mdx- Число - Признак MDX (0/1)$.data[0].datasets[*].rls- Число - Признак RLS (0/1):$.data[0].datasets[*].fields_ref- Массив из Объект - Иерархии полей (пустой массив, если иерархии нет):$.data[0].datasets[*].fields_ref[*].name- Строка - Имя иерархии$.data[0].datasets[*].fields_ref[*].ref- Массив из Объект - Ссылки на поля иерархии:$.data[0].datasets[*].fields_ref[*].ref[*].field_name- Строка - Имя поля$.data[0].datasets[*].fields_ref[*].ref[*].parent_field_name- Строка - Имя старшего поля (пустая строка для корня)
$.data[0].datasets[*].based_type- Число - Базовый тип
$.data[0].field- Массив из Объект - Поля наборов данных:$.data[0].field[*].field_id- Число - Идентификатор поля$.data[0].field[*].dataset_id- Число - Идентификатор набора данных$.data[0].field[*].name- Строка - Имя поля$.data[0].field[*].alias- Строка - Псевдоним поля$.data[0].field[*].type- Строка - Тип поля (string, number, date и т.д.)$.data[0].field[*].bk- Булево - Признак бизнес-ключа$.data[0].field[*].correctable- Булево - Признак корректируемости$.data[0].field[*].expression- Массив из Объект или null - Выражение вычисляемого поля. Каждый элемент:{ "ID": <Число> }$.data[0].field[*].prop- Объект или null - Свойства файлового поля:$.data[0].field[*].prop.fileName- Строка - Имя поля с именем файла$.data[0].field[*].prop.ext- Строка - Имя поля с расширением файла$.data[0].field[*].prop.size- Строка - Имя поля с размером файла$.data[0].field[*].prop.date- Строка - Имя поля с датой файла
$.data[0].report_group- Массив из Объект - Группы отчётов:$.data[0].report_group[*].report_group_id- Число - Идентификатор группы отчётов$.data[0].report_group[*].parent_group_id- Число или null - Идентификатор родительской группы (null для корневой)$.data[0].report_group[*].name- Строка - Имя группы$.data[0].report_group[*].caption- Строка - Заголовок группы$.data[0].report_group[*].options- Строка - Опции (JSON, например"{}")$.data[0].report_group[*].image- Строка - Изображение (путь или ID)$.data[0].report_group[*].menu- Число - Признак отображения в меню (0/1)$.data[0].report_group[*].def- Число - Признак группы по умолчанию (0/1)
$.data[0].report- Массив из Объект - Отчёты:$.data[0].report[*].report_id- Число - Идентификатор отчёта$.data[0].report[*].report_group_id- Число - Идентификатор группы отчётов$.data[0].report[*].name- Строка - Имя отчёта$.data[0].report[*].caption- Строка - Заголовок отчёта$.data[0].report[*].grid- Строка - Сетка отчёта (JSON)$.data[0].report[*].global_filters- Строка - Глобальные фильтры (JSON)$.data[0].report[*].global_categories- Строка - Глобальные категории (JSON)$.data[0].report[*].global_variables- Строка - Глобальные переменные (JSON)$.data[0].report[*].remark- Строка - Примечание$.data[0].report[*].description- Строка - Описание$.data[0].report[*].ord- Число - Порядок сортировки$.data[0].report[*].image_id- Число или null - Идентификатор изображения$.data[0].report[*].options- Строка - Опции (JSON)
$.data[0].report_ro- Массив из Объект - Флаги «только для чтения» отчётов:$.data[0].report_ro[*].report_id- Число - Идентификатор отчёта
$.data[0].report_transformation- Массив из Объект - Трансформации отчётов:$.data[0].report_transformation[*].report_id- Число - Идентификатор отчёта$.data[0].report_transformation[*].version- Строка - Версия трансформации$.data[0].report_transformation[*].settings- Строка - Настройки (JSON)
$.data[0].report_export- Массив из Объект - Шаблоны экспорта (XLSX/PPTX):$.data[0].report_export[*].report_export_id- Число - Идентификатор шаблона экспорта$.data[0].report_export[*].report_id- Число - Идентификатор отчёта$.data[0].report_export[*].container_id- Число - Идентификатор контейнера$.data[0].report_export[*].export_format_id- Число - Идентификатор формата экспорта$.data[0].report_export[*].data- Строка - Содержимое файла (base64)
$.data[0].file- Массив из Объект - Файлы/изображения:$.data[0].file[*].file_id- Число - Идентификатор файла$.data[0].file[*].path- Строка - Путь к файлу$.data[0].file[*].name- Строка - Имя файла$.data[0].file[*].caption- Строка - Заголовок файла$.data[0].file[*].data- Строка - Содержимое файла (base64)
Пример запроса:
{
"object": { "name": "transfer" },
"command": { "name": "export" },
"data": [{
"report_ids": [30],
"dataset_ids": [3],
"report_group_ids": [5, 6]
}]
}
Пример ответа:
{
"mode": "online",
"status": 200,
"message": "",
"data": [{
"version": "1.5.0",
"exported_at": "2026-03-01T12:00:00Z",
"datasources": [
{
"datasource_id": 1,
"driver_id": 1,
"name": "sales_db",
"caption": "БД продаж",
"host": "db.example.local",
"port": 5432,
"base": "sales",
"schema": "public"
}
],
"datasets": [
{
"dataset_id": 3,
"datasource_id": 1,
"name": "sales_ds",
"caption": "Продажи по регионам",
"query": "SELECT id, amount, sale_date, receipt, region, city FROM sales",
"query_rls": "SELECT * FROM sales WHERE region = :user_region",
"limit": 5000,
"cached": 1,
"mdx": 0,
"rls": 1,
"fields_ref": [
{
"name": "Иерархия регионов",
"ref": [
{ "field_name": "city", "parent_field_name": "region" },
{ "field_name": "region", "parent_field_name": "" }
]
}
],
"based_type": 0
}
],
"field": [
{
"field_id": 9,
"dataset_id": 3,
"name": "id",
"alias": "Идентификатор продажи",
"type": "integer",
"bk": true,
"correctable": false,
"expression": null,
"prop": null
},
{
"field_id": 10,
"dataset_id": 3,
"name": "amount",
"alias": "Сумма",
"type": "number",
"bk": false,
"correctable": true,
"expression": null,
"prop": null
},
{
"field_id": 11,
"dataset_id": 3,
"name": "sale_date",
"alias": "Дата продажи",
"type": "date",
"bk": false,
"correctable": false,
"expression": [{ "ID": 1 }, { "ID": 2 }, { "ID": 3 }],
"prop": null
},
{
"field_id": 12,
"dataset_id": 3,
"name": "receipt",
"alias": "Чек",
"type": "file",
"bk": false,
"correctable": false,
"expression": null,
"prop": {
"fileName": "receipt_name",
"ext": "receipt_ext",
"size": "receipt_size",
"date": "receipt_date"
}
}
],
"report_group": [
{
"report_group_id": 6,
"parent_group_id": null,
"name": "analytics",
"caption": "Аналитика",
"def": 0,
"options": "{\"color\":\"blue\"}",
"menu": 1,
"image": ""
},
{
"report_group_id": 5,
"parent_group_id": 6,
"name": "sales_reports",
"caption": "Отчёты по продажам",
"def": 0,
"options": "{}",
"menu": 1,
"image": "folder-blue"
}
],
"report": [
{
"report_id": 30,
"report_group_id": 5,
"name": "sales_summary",
"caption": "Сводка по продажам",
"grid": "{\"columns\":[{\"field\":\"sale_date\",\"title\":\"Дата\"},{\"field\":\"amount\",\"title\":\"Сумма\"}]}",
"global_filters": "{\"region\":\"all\"}",
"global_categories": "{\"by\":\"region\"}",
"global_variables": "{\"currency\":\"RUB\"}",
"remark": "Обновляется ежемесячно",
"description": "Ежемесячная сводка продаж по регионам",
"ord": 1,
"image_id": 7,
"options": "{\"theme\":\"light\"}"
}
],
"report_ro": [{ "report_id": 30 }],
"report_transformation": [
{
"report_id": 30,
"version": "2",
"settings": "{\"steps\":[{\"type\":\"filter\",\"field\":\"amount\",\"op\":\">\",\"value\":0}]}"
}
],
"report_export": [
{
"report_export_id": 12,
"report_id": 30,
"container_id": 1,
"export_format_id": 2,
"data": "UEsDBBQABgAIAAAAIQ..."
}
],
"file": [
{
"file_id": 7,
"path": "images/reports",
"name": "sales_icon.png",
"caption": "Иконка отчёта продаж",
"data": "iVBORw0KGgoAAAANSUhEUg..."
}
]
}]
}
Импорт объектов с другого портала (transfer.import)
Команда импортирует пакет (Package), полученный командой transfer.export. Объекты переносятся с сохранением их ID — в отличие от старого импорта отчётов, где создаётся «такой же» объект с новым ID. Для каждого объекта в пакете: если объект с данным ID отсутствует — он создаётся; если присутствует — обновляется. Лишние объекты на целевом портале не удаляются.
Атомарность: либо импортируются все объекты из пакета, либо ничего. При любой ошибке выполняется откат, целевой портал остаётся без изменений.
Требует маппинг источников данных целевого портала (datasource_id в датасетах).
Права доступа:
- Требует авторизации
- Доступна ролям: администратор, разработчик
Спецификации:
- URL: https://
/v1/ api/transfer — где — адрес вашего экземпляра Modus BI. - Тип запроса:
POST - Тип данных запроса:
JSON
Параметры запроса
В разделе рассмотрено тело запроса команды transfer.import. Параметры представлены в порядке: Параметр, Тип, Описание, Примечание.
| Параметр | Тип | Описание | Примечание |
|---|---|---|---|
$.object.name |
Строка | Имя объекта: "transfer" |
Обязательный параметр |
$.command.name |
Строка | Имя команды: "import" |
Обязательный параметр |
$.data[0].package |
Объект | Пакет — объект экспорта. |
Обязательный параметр. Структура совпадает с полем |
|
|
Массив из Объект | Маппинг источников данных (source_datasource_id → target_datasource_id) |
Обязательный параметр. Обязателен, если пакет содержит наборы данных; если датасетов нет — можно не передавать:
|
| Число |
ID источника в пакете |
Обязательный параметр | |
| Число |
ID целевого источника на портале |
Обязательный параметр |
Валидация: все datasource_id из пакета должны быть покрыты маппингом.
Параметры ответа
В разделе рассмотрено тело ответа. Параметры представлены в порядке: Параметр, Тип, Описание.
$.mode- Строка - Состояние сервиса портала$.status- Число - Статус выполнения. 200 - команда выполнена, иное значение - возникла ошибка$.message- Строка - Описание ошибки. При нескольких ошибках валидации — объединение через\n$.data[0]- Объект - Подтверждение импорта (при успехе):$.data[0].imported- Булево - Признак успешного импорта (true)$.data[0].message- Строка - Сообщение о результате («Объекты перенесены с сохранением ID»)
Пример запроса:
{
"object": { "name": "transfer" },
"command": { "name": "import" },
"data": [{
"package": {
"version": "1.0",
"exported_at": "2025-03-01T12:00:00Z",
"datasources": [...],
"datasets": [...],
"field": [...],
"report_group": [...],
"report": [...],
"report_ro": [...],
"report_transformation": [...],
"report_export": [...],
"file": []
},
"datasource_mappings": [
{ "source_datasource_id": 1, "target_datasource_id": 96 },
{ "source_datasource_id": 2, "target_datasource_id": 97 }
]
}]
}
Пример ответа:
{
"mode": "online",
"status": 200,
"message": "",
"data": [{
"imported": true,
"message": "Объекты перенесены с сохранением ID"
}]
}
Важные замечания
- Пароли из источников данных не экспортируются (поле отсутствует в пакете). После импорта потребуется заново настроить подключение к источникам данных на целевом портале.
- Маппинг источников данных обязателен. Каждый источник данных из пакета должен быть сопоставлен с существующим источником на целевом портале.
- Атомарность импорта. Если импорт прерывается ошибкой, все изменения откатываются. Целевой портал остаётся в неизменном состоянии.
- Сохранение ID. При импорте объекты переносятся с теми же идентификаторами, что и в исходном портале. Это ключевое отличие от старого механизма импорта отчётов.
- Связанные объекты. В пакет автоматически включаются все связанные данные: трансформации, шаблоны экспорта (XLSX/PPTX), изображения.
Коды ошибок и ответ при ошибке
При любой ошибке импорт откатывается целиком — целевой портал остаётся без изменений.
Конверт ошибки не содержит поле data. Формат: mode, status, message. В message к тексту ошибки добавляется идентификатор вызова (call id) на новой строке; при нескольких ошибках валидации они объединяются через \n.
Примечание — опционально в конверт могут добавляться поля server_error (проблема с лицензией) и metadata (отладочные данные, только для роли с правом отладки).
Коды ошибок
|
status |
Причина |
|
400 |
Валидация: не покрыт маппинг, нет родительской группы, целевой источник не найден, нет права доступа |
|
406 |
Неверный формат запроса: нет |
|
500 |
Внутренняя ошибка (ошибка транзакции и т.п.), выполнен откат |
Пример кода — не покрытые маппингом источники данных
{
"mode": "online",
"status": 400,
"message": "Источники данных не покрыты маппингом: datasource_id=2\ndatasource_id=3\n[call:1733817600123456789]"
}