# Интеграция Baserow и Power BI - визуализация через API

> Бесплатный REST API Baserow отдаёт данные таблиц в Power BI по токену: как настроить Web-коннектор, Power Query, пагинацию и стабильные ID полей.

Source: https://opennix.org/docs/baserow/integrations/power-bi-integration/


Power BI не получает данные от Baserow автоматически - он сам подключается к бесплатному REST API Baserow через встроенный Web-коннектор, аутентифицируется токеном базы данных и превращает строки таблиц в интерактивные отчёты; ниже - архитектура связки, пошаговая настройка от токена до первой визуализации, обработка пагинации через M-код и таблица соответствия типов полей.

## Когда использовать эту интеграцию

- **Отчёты для руководства.** Команда ведёт проекты в Baserow, а руководству нужен наглядный визуальный обзор статусов и загрузки ресурсов в реальном времени.
- **Анализ из нескольких источников.** Данные разбросаны между Baserow, Excel и SQL Server - Power BI объединяет все три источника в единый отчёт.
- **Автоматизация регулярной отчётности.** Вместо еженедельного ручного экспорта CSV из Baserow подключение по API с расписанием обновления убирает эту рутину.
- **Отчёты для внешних клиентов.** Готовые визуализации Power BI встраиваются на сайт или рассылаются в виде PDF без открытия доступа к самой базе.
- **Контроль соответствия требованиям.** Данные о проверках и соответствии, которые ведутся в Baserow, превращаются в стандартизированные отчёты с датой формирования.
- **Мониторинг склада.** Уровни запасов из Baserow визуализируются с автоматическими визуальными предупреждениями при снижении остатков.

![Схема интеграции Baserow и Power BI](/images/baserow/integrations/power-bi-integration-hero.png)

## Как устроена интеграция

Направление передачи данных всегда одно: Baserow не отправляет данные в Power BI, Power BI сам их запрашивает. Какие именно данные и с какой периодичностью - определяется параметрами URL-запроса на стороне Power BI.

```
База данных Baserow (источник данных)
    ↓
REST API эндпоинт (отдаёт JSON)
    ↓
Web-коннектор Power BI (запрашивает данные)
    ↓
Редактор Power Query (превращает JSON в таблицы)
    ↓
Модель данных Power BI (готова к визуализации)
```

## Что понадобится

- Аккаунт Baserow (облачный или self-hosted) с доступом к рабочему пространству, где лежит нужная база.
- [Power BI Desktop](https://powerbi.microsoft.com/desktop/) актуальной версии.
- Базовое понимание структуры базы данных: таблицы, строки, поля, связи.
- [Токен базы данных](/docs/baserow/webhook-api/personal-api-tokens/) Baserow для аутентификации запросов.

## Шаг 1. Создание токена базы данных

Токен базы данных подтверждает право на доступ к конкретным таблицам Baserow - без него Web-коннектор Power BI не сможет прочитать ни одной строки.

1. Войдите в Baserow и откройте меню профиля в правом верхнем углу.
2. Перейдите в **Settings → Database tokens**.
3. Нажмите **+ Create token**.
4. Выберите рабочее пространство и задайте токену понятное имя, например `Power BI Integration`.
5. Ограничьте область действия токена только теми таблицами, которые нужно визуализировать.
6. Настройте права: чтение строк обязательно, создание и изменение - опционально, если Power BI не должен писать данные обратно в Baserow.
7. Скопируйте появившуюся строку токена - она отображается один раз.

Подробнее о разнице между токеном базы данных и JWT-токеном - в статье [«Токен базы данных Baserow»](/docs/baserow/webhook-api/personal-api-tokens/). Токен даёт доступ к данным строк - храните его так же осторожно, как пароль, и не публикуйте в открытых репозиториях.

![Создание токена базы данных Baserow для Power BI](/images/baserow/integrations/power-bi-integration-database-token.jpg)

## Шаг 2. URL эндпоинта таблицы

Чтобы получить список строк, Power BI выполняет `GET`-запрос к эндпоинту таблицы. Базовый формат адреса:

```
https://api.baserow.io/api/database/rows/table/[TABLE_ID]/
```

Как устроен этот адрес и что означают его части - в статье [«REST API базы данных Baserow»](/docs/baserow/webhook-api/database-api/). ID таблицы можно найти прямо в адресной строке браузера, когда таблица открыта, или другими способами, описанными в статье [«Как найти ID базы данных и таблицы Baserow»](/docs/baserow/webhook-api/database-and-table-id/).

К адресу добавляются параметры запроса:

- `user_field_names=true` - возвращает читаемые названия полей вместо `field_124`.
- `size=200` - максимальное число строк на одну страницу ответа (значение по умолчанию - 100).

Итоговый URL выглядит так:

```
https://api.baserow.io/api/database/rows/table/4567/?user_field_names=true&size=200
```

## Шаг 3. Подключение через Web-коннектор Power BI

1. Откройте Power BI Desktop и создайте новый или откройте существующий отчёт.
2. На вкладке **Home** нажмите **Get data** и выберите коннектор **Web**.
3. В диалоговом окне переключитесь в режим **Advanced**.
4. Вставьте адрес эндпоинта таблицы в поле URL.
5. В разделе заголовков HTTP-запроса добавьте параметр **Authorization** со значением `Token [ВАШ_ТОКЕН]` - слово «Token» и пробел перед самим токеном обязательны.
6. Нажмите **OK**.

![Подключение через Web-коннектор Power BI](/images/baserow/integrations/power-bi-integration-web-connector.jpg)

Если аутентификация прошла успешно, откроется редактор Power Query с предпросмотром данных. Учётные данные Power BI запоминает - изменить их позже можно через **Home → Transform Data → Data source settings**.

![Предпросмотр данных Baserow в Power Query Editor](/images/baserow/integrations/power-bi-integration-power-query-editor.png)

## Шаг 4. Очистка данных и типы значений

JSON-ответ Baserow разворачивается в Power Query не в готовом виде - его нужно привести к табличной структуре:

1. **Удалите служебные столбцы** `count`, `next` и `previous` - они не содержат данных строк и нужны только для пагинации.
2. **Переименуйте столбцы**, у которых сохранился префикс `results.` (например, `results.id`), в понятные названия.
3. **Отфильтруйте строки** при необходимости через выпадающий список фильтра в заголовке столбца.
4. **Проверьте тип данных** каждого столбца на вкладке **Transform** - даты и числа особенно часто определяются неверно.

![Настройка типов данных в Power Query для Baserow](/images/baserow/integrations/power-bi-integration-data-types.jpg)

Поля с вложенной структурой требуют отдельной обработки:

- **Поле с одним выбором** - разверните столбец, чтобы получить значение `value`.
- **Поле с множественным выбором** - Power Query возвращает вложенный список; сначала разверните его в новые строки, затем извлеките `value`. Для каждого элемента списка Power BI создаёт отдельную строку, дублируя остальные данные исходной записи.
- **Поле файла** - возвращает список объектов файла. Чтобы получить только URL первого файла, добавьте вычисляемый столбец с формулой M: `Table.AddColumn(Source, "File_URL", each try [file_field]{0}[url] otherwise null)`.

## Шаг 5. Первая визуализация

1. В редакторе Power Query нажмите **Close & Apply**.
2. На панели данных справа появятся поля из Baserow, готовые к использованию.
3. Перетащите поле на холст отчёта - Power BI сразу создаст базовый график.
4. Для столбчатой диаграммы: перетащите поле статуса в ось X, а поле идентификатора - в ось Y с агрегацией «Count».
5. Каждое нажатие **Refresh** обновляет визуализацию данными из Baserow на текущий момент.

![Построение визуализации на данных Baserow в Power BI](/images/baserow/integrations/power-bi-integration-build-visuals.jpg)

## Пагинация: как получить все строки

Baserow отдаёт максимум 200 строк за один запрос. Если в таблице 1000 строк, потребуется 5 запросов - и это нужно либо задать вручную, либо автоматизировать.

**Ручной способ** подходит для небольших таблиц (менее 1000 строк) - достаточно увеличить параметр `size` до максимума:

```
https://api.baserow.io/api/database/rows/table/12345/?user_field_names=true&size=200
```

**Автоматический способ** нужен, когда строк больше, чем помещается на одну страницу. В редакторе Power Query откройте **Home → Advanced Editor** и замените код на рекурсивный M-скрипт, который сам переходит по ссылке `next`, пока она не станет пустой:

```
let
    BaseUrl = "https://api.baserow.io/",
    RelativePathStart = "api/database/rows/table/[YOUR_TABLE_ID]/",
    Token = "Token [YOUR_API_TOKEN]",

    FetchPage = (relPath) =>
        let
            Source = Json.Document(Web.Contents(BaseUrl, [
                RelativePath = relPath,
                Headers = [Authorization=Token]
            ])),
            results = Source[results],
            nextURL = Source[next]
        in
            {results, nextURL},

    FetchAllPages = (relPath) =>
        let
            page = FetchPage(relPath),
            results = page{0},
            nextURL = page{1},
            newRelPath = if nextURL <> null then Text.Replace(nextURL, BaseUrl, "") else null,
            nextResults = if newRelPath <> null then @FetchAllPages(newRelPath) else {}
        in
            List.Combine({results, nextResults}),

    SourceList = FetchAllPages(RelativePathStart & "?user_field_names=true&size=200"),
    #"Converted to Table" = Table.FromList(SourceList, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    FieldNames = List.Distinct(List.Combine(List.Transform(SourceList, each Record.FieldNames(_)))),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", FieldNames, FieldNames)
in
    #"Expanded Column1"
```

Замените `[YOUR_TABLE_ID]` и `[YOUR_API_TOKEN]` на реальные значения; для self-hosted Baserow измените и `BaseUrl` на адрес своего сервера. После вставки этого кода типы данных для всех столбцов нужно проверить вручную - скрипт разворачивает поля динамически и не может угадать нужный тип.

![Автоматическая пагинация через M-код в Power Query](/images/baserow/integrations/power-bi-integration-pagination.jpg)

## Обновление данных: вручную или по расписанию

Изменение строки в Baserow не появляется в Power BI мгновенно - обновление нужно запускать явно:

- **В Power BI Desktop** - кнопка **Refresh** на вкладке Home заново запрашивает API и обновляет визуализации.
- **В облачном сервисе Power BI** - можно настроить расписание обновления (например, каждое утро в 9:00), но поскольку подключение использует токен в заголовке запроса, сервис обычно не может обновлять такие Web-источники без установленного **On-Premises Data Gateway**.

![Настройка расписания обновления данных Power BI](/images/baserow/integrations/power-bi-integration-refresh.jpg)

## Query folding и фильтрация на уровне API

Web-коннекторы не поддерживают query folding - все преобразования выполняются локально в Power BI, а не на стороне источника. Чтобы не тянуть в отчёт лишние строки, фильтрацию и сортировку стоит выполнять на уровне самого API-запроса через параметры URL, например `filter__Status__equal=Active`. Подробнее о синтаксисе фильтров - в статье [«Фильтры в Baserow»](/docs/baserow/views/filters-in-baserow/).

## Соответствие типов полей Baserow и Power BI

| Тип поля Baserow | Тип данных Power BI | Примечание |
|---|---|---|
| Текст | Text | Прямое соответствие |
| Long text | Text | Прямое соответствие |
| Number | Decimal Number / Whole Number | Выбор зависит от числа знаков после запятой |
| Rating | Whole Number | Звёзды становятся целыми числами (1-5) |
| Boolean | True/False | Прямое соответствие |
| Date | Date | Формат ISO 8601 (YYYY-MM-DD) |
| Last Modified | DateTime | Метка времени с часовым поясом |
| Created On | DateTime | Метка времени с часовым поясом |
| URL | Text | Хранится как текст, ссылка активна в визуализации |
| Email | Text | Хранится как текст |
| Phone Number | Text | Хранится как текст, чтобы сохранить формат |
| Single select | Text | Возвращает выбранный вариант |
| Multiple select | Text (список) | Требует разбиения в Power Query |
| File | Text (JSON) | Массив объектов файла со ссылками |
| Link to table | Text (JSON) | Массив ID и значений связанных записей |
| Lookup | Text | Возвращает найденное значение |
| Formula | Зависит от формулы | Определяется типом результата формулы |
| Rollup | Number | Агрегированное значение по связанным записям |
| Count | Whole Number | Количество связанных записей |
| Autonumber | Whole Number | Последовательный идентификатор |

## Поле «Связь с таблицей»: два способа обработки

[Поле связи с таблицей](/docs/baserow/field-types/link-to-table-field/) возвращает список идентификаторов и значений связанных записей - Power BI не умеет автоматически строить связи между такими таблицами, их нужно задать вручную в модели данных.

**Способ 1 - для простых отчётов.** Разверните связанный столбец прямо в Power Query: сначала в новые строки, затем до значения `value`. Получится одна плоская таблица, удобная для небольших наборов данных.

**Способ 2 - для отчётов со сложными связями.** Если объединять поле связи в Power Query на десятках тысяч строк, текстовые значения дублируются в каждой строке. Вместо объединения загрузите обе таблицы отдельно, откройте **Model View** и вручную соедините столбец идентификатора одной таблицы со столбцом идентификатора другой. Такая модель работает быстрее и позволяет фильтровать сразу несколько таблиц одним срезом.

## ID полей вместо имён - для продакшн-отчётов

Параметр `user_field_names=true` удобен на этапе разработки, но если название поля в Baserow изменится, обновление отчёта в Power BI завершится ошибкой - он не найдёт столбец с прежним именем.

Для продакшн-отчётов используйте необработанные ID полей (`field_482`) вместо читаемых названий: в Power Query переименуйте столбец `field_482` в понятное имя уже после импорта, через правый клик → **Rename**. Идентификатор поля не меняется, даже если название поля в Baserow редактируется - отчёт продолжит работать.

![Использование ID полей вместо имён в Power Query](/images/baserow/integrations/power-bi-integration-field-ids.png)

## Решение типичных ошибок

| Код ошибки | Причина | Решение |
|---|---|---|
| 401 Unauthorized | Некорректный токен | Проверьте, что перед токеном указано слово «Token» с пробелом |
| 404 Not Found | Неверный URL | Проверьте ID таблицы и убедитесь, что вставлен API-адрес, а не адрес из браузера |
| Expression.Error | Ошибка разбора JSON | Поле, которое разворачивается, содержит null - добавьте шаг «Remove Errors» или используйте `try/otherwise` |
| Credentials Required | Нет шлюза | Обновление в облаке требует установленного On-Premises Data Gateway |
| «This dataset includes a dynamic data source» | Адрес формируется динамически внутри цикла | Используйте параметр `RelativePath` в M-коде - он сообщает Power BI, что базовый адрес статичен и обновление можно выполнять в облаке |

## Часто задаваемые вопросы

**Нужен ли платный тариф Baserow для этой интеграции?** Нет - подключение работает через бесплатный REST API и токен базы данных, доступные в open-source редакции Baserow без ограничений.

**Можно ли писать данные из Power BI обратно в Baserow?** Web-коннектор Power BI предназначен для чтения данных. Запись строк через API технически возможна отдельными запросами, но не входит в стандартный сценарий этой интеграции.

**Что делать, если в таблице больше 200 строк?** Использовать автоматическую пагинацию через M-код, описанную выше - она сама переходит по ссылке `next`, пока не получит все страницы.

Следующий шаг - статья [«Интеграция Baserow с Notion»](/docs/baserow/integrations/notion-integration/): как синхронизировать записи между двумя инструментами через тот же REST API.

