# Arrow ADBC и dbt v2

Этот документ содержит технические рекомендации для партнёров и поставщиков dbt по проектированию, разработке и сопровождению драйверов ADBC (Apache Arrow Database Connectivity) для dbt v2 — нового движка dbt.

dbt v2 использует ADBC как единый слой драйверов для бесшовной высокопроизводительной интеграции с платформами данных. Разработка драйвера ADBC — первый шаг к подключению dbt v2 к новой платформе.

## Почему dbt v2 использует ADBC

dbt v2 представляет собой значительный шаг в развитии движка dbt с минимальными изменениями в подходе к написанию кода. Написанный на Rust, dbt v2 обеспечивает высокую скорость, понимание языка и бесшовную интеграцию со множеством хранилищ данных. Ключевая особенность нового движка — использование ADBC — современного открытого стандарта проекта Apache Arrow, который упрощает обмен данными в колоночном формате между платформами.

Ранее адаптерам dbt v1 требовалась собственная логика подключения для каждой платформы данных. dbt v2 совершенствует эту модель за счёт единого слоя драйверов ADBC, который предлагает несколько ключевых преимуществ:

* **Стандартизация**: ADBC стандартизирует общие возможности платформ в рамках единого интерфейса.
* **Производительность**: драйверы используют колоночный формат представления данных в памяти Arrow для эффективного выполнения запросов с минимальным количеством преобразований.
* **Удобство сопровождения**: драйверы ADBC следуют общей спецификации, что снижает сложность реализации новых адаптеров.

## Технический обзор

В этом техническом описании рассматривается спецификация ADBC. Спецификация сохраняет обратную совместимость, поэтому приведённые здесь рекомендации остаются актуальными по мере её развития. За актуальной информацией и подробной документацией обращайтесь к [документации ADBC](https://arrow.apache.org/adbc/current/), которая является основным достоверным источником.

API ADBC предоставляет широкий набор возможностей, но реализовывать их все необязательно. В этом разделе рассматривается набор интерфейсов API, необходимый для совместимости с dbt v2.

### Язык программирования

**Кратко: используйте Go.**

Одно из явных преимуществ Arrow ADBC — переносимость. Вы можете писать драйверы на разных языках и загружать их через менеджеры драйверов. Такая переносимость позволяет dbt v2 (написанному на Rust) использовать драйверы, написанные на других языках.

Для совместимости с dbt v2 драйверы должны:

* Компилироваться в разделяемые библиотеки, которые можно загрузить из любой программы
* Поставляться в виде самодостаточного бинарного файла для конкретной платформы

Мы рекомендуем использовать **Go**, хотя Rust и C++ тоже подходят. У Go есть среда выполнения и сборщик мусора, но он спроектирован так, чтобы компилироваться в корректно работающие разделяемые библиотеки—в отличие от таких языков, как C# или Java. Самодостаточный бинарный файл позволяет пользователям скачать драйвер и сразу запустить его без настройки интерпретатора. Компилируемые языки, такие как Go, также позволяют dbt v2 и его драйверам напрямую совместно использовать память через FFI без внешних зависимостей.

### Спецификации ADBC

В этом разделе рассматриваются минимальные требования к драйверу ADBC, совместимому с dbt v2. Подробную информацию о спецификации ADBC и разработке драйверов см. в [руководстве по разработке драйверов ADBC](https://arrow.apache.org/adbc/current/driver/authoring.html).

Драйверы состоят из нескольких ключевых абстракций:

1. **Driver**: загрузите драйвер для создания объектов Database.
2. **Database**: создавайте объекты Database и задавайте параметры конфигурации (включая аутентификацию). Используйте объекты Database для открытия соединений.
3. **Connection**: устанавливайте соединения с хранилищем данных. Соединения создают объекты Statement.
4. **Statement**: задавайте параметры и SQL-запросы для объектов Statement, а затем выполняйте их в хранилище данных.

dbt v2 достигает высокой производительности за счёт интенсивного параллелизма, поэтому во время выполнения проекта следует ожидать большого количества одновременных соединений.

### Аутентификация

Драйверы выполняют аутентификацию с помощью параметров в формате «ключ — значение», заданных для объекта Database. dbt v2 преобразует параметры из файлов `profiles.yml`, созданных пользователями, перед их передачей драйверу. Например, параметр, который dbt называет `client_secret` в профиле Snowflake, задаётся в драйвере как `adbc.snowflake.sql.client_option.client_secret`.

Полный пример того, как dbt v2 преобразует параметры профиля, см. в [исходном коде аутентификации Snowflake](https://github.com/dbt-labs/dbt-fusion/blob/main/crates/dbt-auth/src/snowflake/mod.rs).

Дополнительную информацию о настройке профилей см. в разделе [Профили dbt](https://docs.getdbt.tech/docs/local/profiles.yml.md).

#### Кэширование учётных данных

Простые методы аутентификации (например, имя пользователя и пароль, сохранённые в `profiles.yml`) поддерживают полностью параллельное создание соединений без специальной обработки.

Для методов аутентификации, требующих взаимодействия с браузером (OAuth типа user-to-machine, SSO или MFA), реализуйте кэширование учётных данных. Из-за высокой степени параллелизма в dbt v2 без кэширования каждое новое соединение будет снова запрашивать у пользователя аутентификацию.

Кэш учётных данных для аутентификации через браузер должен:

* Блокировать новые соединения до тех пор, пока первое соединение не будет установлено и не сохранит токен в памяти (чтобы избежать проблемы «громового стада»).
* Обновлять токен при его аннулировании, используя тот же принцип блокировки.
* Использовать общее для процессов хранилище на основе файловой системы для поддержки LSP, который работает в отдельном процессе.

Такое кэширование критически важно для любого варианта аутентификации через браузер или с использованием MFA, но не требуется для простой аутентификации по учётным данным.

## Обязательные API

В этом разделе рассматривается минимальный набор API для совместимости с dbt v2. Требования включают:

* Аутентификацию через параметры.
* Выполнение SQL-запросов.
* Запросы метаданных для определения состояния удалённого хранилища данных (некоторые функции получения метаданных на уровне соединения могут использовать менее затратные или более производительные API для получения схем таблиц).

Эти требования не являются исчерпывающими. dbt Labs рекомендует реализовать спецификацию ADBC полностью, чтобы принести пользу как dbt v2, так и сообществу ADBC в целом.

#### Driver

| Метод         | Описание                          |
| ------------- | --------------------------------- |
| `NewDatabase` | Создать новый экземпляр Database. |

#### Database

| Метод        | Описание                                                |
| ------------ | ------------------------------------------------------- |
| `SetOptions` | Задать параметры конфигурации (включая аутентификацию). |
| `Open`       | Открыть соединение.                                     |
| `Close`      | Закрыть объект Database.                                |

#### Connection

| Метод            | Описание                                         |
| ---------------- | ------------------------------------------------ |
| `GetObjects`     | Получить метаданные из хранилища данных.         |
| `GetTableSchema` | Получить метаданные схем таблиц.                 |
| `NewStatement`   | Создать объект Statement для выполнения запроса. |
| `Close`          | Закрыть соединение.                              |

#### Statement

| Метод           | Описание                               |
| --------------- | -------------------------------------- |
| `SetOption`     | Задать параметры запросов.             |
| `SetSqlQuery`   | Задать текст SQL-запроса.              |
| `ExecuteQuery`  | Выполнить запрос и вернуть результаты. |
| `ExecuteUpdate` | Выполнить DML-запросы.                 |
| `Close`         | Закрыть объект Statement.              |
