Перейти к содержимому
Последнее обновление

Адаптер dbt

dbt управляет этапом преобразования данных в процессе ELT (извлечение, загрузка, преобразование). Адаптер dbt-for-apache-doris компилирует модели dbt в SQL для Doris и выполняет операции создания таблиц, преобразования данных, тестирования и документирования через порт запросов MySQL процесса Doris Frontend (FE).

Исходные данные уже должны быть доступны для запросов через Doris: в таблицах Internal Catalog или через настроенные External Catalog. Адаптер выполняет преобразования; он не загружает и не синхронизирует исходные данные.

предупреждение

dbt-for-apache-doris предоставляется и поддерживается VeloDB. Он не входит в проект Apache Doris, не выпускается и не одобряется сообществом Apache Doris. Оцените адаптер перед использованием в промышленной среде, проверьте целостность пакета и сведения о его выпуске, а также соблюдайте лицензию стороннего проекта. О проблемах с адаптером сообщайте в проект dbt-for-apache-doris.

Требования к среде​

КомпонентТребование
Python3.10 или новее
dbt Core1.12.x (устанавливается вместе с адаптером)

Выпущенные версии​

Версия
1.1.1
1.1.0

Установка​

В следующих командах в качестве примера установки используется опубликованный выпуск v1.1.1. Чтобы установить другой выпуск, замените версию в спецификации пакета для pip.

Установите адаптер из PyPI в изолированной среде Python:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install "dbt-for-apache-doris==1.1.1"
dbt --version

В Windows PowerShell:

py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install "dbt-for-apache-doris==1.1.1"
dbt --version

Для этого примера раздел Plugins в выводе dbt --version должен содержать doris: 1.1.1. dbt Core и MySQL Connector/Python устанавливаются как зависимости.

Настройка подключения​

Создайте проект dbt:

dbt init doris_demo
cd doris_demo

Добавьте конфигурацию подключения к Doris в ~/.dbt/profiles.yml. Не храните учетные данные в системе контроля версий; в этом примере пароль считывается из переменной среды:

doris_demo:
target: dev
outputs:
dev:
type: doris
host: 127.0.0.1
port: 9030
username: dbt_user
password: "{{ env_var('DORIS_PASSWORD') }}"
schema: analytics
threads: 4
ПараметрРекомендуемое значениеПоведение
typeДолжно быть dorisВыбирает адаптер Doris
hostЯвно укажите адрес Doris FEЕсли параметр не задан, базовая конфигурация учетных данных использует 127.0.0.1; в диалоге dbt init значение по умолчанию отсутствует
portОбычно 9030Если параметр не задан, используется 9030; это порт запросов FE, а не порт HTTP
usernameЯвно укажите отдельного пользователя DorisЕсли параметр не задан, базовая конфигурация учетных данных использует root; в диалоге dbt init значение по умолчанию отсутствует
passwordСчитывайте из переменной средыПо умолчанию используется пустая строка
schemaУкажите целевую базу данных DorisВ диалоге dbt init по умолчанию предлагается dbt; в базовой конфигурации учетных данных значение по умолчанию равно None
threadsЗадайте с учетом возможностей FE и нагрузкиВ диалоге dbt init по умолчанию предлагается 1
databaseНе указывайте для Internal Catalog; для внешнего целевого объекта укажите существующий Doris CatalogСоответствует Doris Catalog в v1.1.1

В v1.1.1 путь dbt database.schema.identifier соответствует пути Doris catalog.database.table. Для Internal Catalog не указывайте database, а в schema задайте базу данных Doris. Для внешнего целевого объекта укажите в database существующий Doris Catalog, а в schema базу данных в этом Catalog. Адаптер может попытаться создать отсутствующую целевую базу данных, если Catalog это поддерживает. Учетной записи dbt нужны разрешения на чтение источников, а также на создание, изменение, удаление целевых объектов и запись в них. Поддержка записи в External Catalog также зависит от коннектора Doris.

Убедитесь, что в dbt_project.yml указан тот же профиль:

name: doris_demo
version: "1.0.0"
config-version: 2
profile: doris_demo

model-paths: ["models"]

models:
doris_demo:
+materialized: view

В macOS или Linux проверьте подключение командой:

export DORIS_PASSWORD='your_password'
dbt debug

В Windows PowerShell:

$env:DORIS_PASSWORD = 'your_password'
dbt debug

Построение первой модели​

Следующий SQL создает исходную таблицу для этого примера. Коэффициент репликации 1 подходит только для кластера разработки с одним BE:

CREATE DATABASE IF NOT EXISTS raw;

CREATE TABLE IF NOT EXISTS raw.orders (
order_id BIGINT,
customer_id BIGINT,
order_time DATETIME,
amount DECIMAL(18, 2),
status VARCHAR(20),
updated_at DATETIME,
is_valid BOOLEAN
)
DUPLICATE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 1
PROPERTIES ("replication_num" = "1");

INSERT INTO raw.orders VALUES
(1, 101, '2026-08-01 10:00:00', 20.00, 'PAID', '2026-08-01 10:05:00', true),
(2, 102, '2026-08-01 11:00:00', 35.00, 'PAID', '2026-08-01 11:05:00', true);

Объявите источник в models/sources.yml:

version: 2

sources:
- name: raw
schema: raw
tables:
- name: orders

Создайте models/fct_daily_sales.sql:

{{
config(
materialized='table',
duplicate_key=['order_date'],
distributed_by=['order_date'],
buckets=1,
properties={'replication_num': '1'}
)
}}

select
cast(order_time as date) as order_date,
sum(amount) as sales_amount
from {{ source('raw', 'orders') }}
group by cast(order_time as date)

Добавьте тесты данных в models/schema.yml:

version: 2

models:
- name: fct_daily_sales
description: Daily sales summary
columns:
- name: order_date
description: Order date
data_tests:
- not_null
- unique
- name: sales_amount
description: Daily sales amount
data_tests:
- not_null

Запустите модель и тесты:

dbt build --select fct_daily_sales

При успешном выполнении создается analytics.fct_daily_sales. Для промышленной среды задайте количество реплик и бакетов в соответствии с конфигурацией кластера.

Если источник находится в другой базе данных Doris, предпочтительно задать schema напрямую:

sources:
- name: finance
schema: finance_raw
tables:
- name: payments

В v1.1.1 параметр database источника задает имя Doris Catalog. Для чтения из другой базы данных в Internal Catalog задайте только schema, как показано выше. В проектах, где для источников в других базах данных в v1.1.0 использовалось database: finance_raw, перед обновлением необходимо перенести это значение в schema.

External Catalog в v1.1.1​

Адаптер может читать источники в External Catalog и получать сведения об их таблицах и столбцах для dbt docs generate. Сначала создайте Catalog в Doris, затем укажите его имя в поле database источника:

sources:
- name: lakehouse
database: hive_catalog
schema: ods
tables:
- name: orders

{{ source('lakehouse', 'orders') }} разрешается в hive_catalog.ods.orders. Поле schema задает имя базы данных внутри этого Catalog. Адаптер поддерживает имена объектов с указанием Catalog; при этом именно коннектор каждого Catalog определяет, какие операции DDL и записи может выполнять Doris.

Чтобы создать целевую таблицу Iceberg, сначала настройте Iceberg Catalog с поддержкой записи. Задайте следующие поля в существующей конфигурации подключения профиля:

database: iceberg_catalog
schema: analytics

Создайте models/iceberg_sample.sql:

{{ config(materialized='table', engine='iceberg') }}

select cast(1 as int) as id

Явное приведение к INT позволяет избежать автоматического определения типа как TINYINT, который не поддерживается для столбцов Iceberg.

Выполните dbt run --select iceberg_sample. Команда создает iceberg_catalog.analytics.iceberg_sample. Catalog должен существовать; его база данных должна существовать либо dbt должен иметь возможность ее создать, а целевой объект должен поддерживать запись. Параметр engine='iceberg' добавляет явное указание движка; если не задавать engine, Doris определяет его по целевому Catalog. Определение движка по Catalog проверено на Doris 4.1.3. Более ранние выпуски Doris могут требовать явного указания движка.

Целевой объект IcebergПоведение в v1.1.1
tableСоздает таблицу Iceberg; при повторных запусках заменяет ее через создание резервной копии и переименование
incrementalПоддерживает append, merge, insert_overwrite и microbatch, описанные ниже
Seed и SnapshotПоддерживаются; публикация Snapshot и полное обновление Seed используют резервную копию и переименование. Обычная перезагрузка использует INSERT OVERWRITE для непартиционированных таблиц; перезагрузка партиционированных таблиц использует нативный MERGE и требует V2+. Для партиционированных Seed версии V1 используйте dbt seed --full-refresh
view и materialized_viewЦелевые объекты должны находиться в Internal Catalog; представления и материализованные представления Internal Catalog могут обращаться к источникам в External Catalog

Для Iceberg стратегии merge, microbatch и перезагрузка партиционированных Seed требуют выпуска Doris с нативной поддержкой Iceberg MERGE INTO и таблицы Iceberg V2 или новее. Эти сценарии проверены на Doris 4.1.3; в документации Doris поддержка Iceberg MERGE отмечена как экспериментальная начиная с 4.1.0. Замена внешней таблицы не атомарна: между переименованиями ее имя ненадолго становится недоступным, а при сбое старая таблица может остаться под резервным именем. Перед использованием в промышленной среде проверьте выпуск Doris, коннектор Catalog и процедуру восстановления в изолированном тестовом проекте.

Адаптер отклоняет объявления constraints на уровне модели или столбцов до записи в целевой объект типа Table, View, Incremental или MV. Контракты моделей по-прежнему проверяют имена и типы столбцов. Для проверки данных после записи используйте data_tests, например not_null; такие тесты не создают ограничений, обеспечиваемых базой данных.

Пять запускаемых демонстрационных проектов Doris охватывают модели, тесты, источники в других базах данных, инкрементальную обработку, снимки и асинхронные материализованные представления. По умолчанию в демонстрационной среде используется dbt-for-apache-doris==1.1.1.

Материализации​

dbt-for-apache-doris поддерживает следующие основные материализации:

МатериализацияОбъект Doris или поведениеСценарий использования
viewПредставление Doris в Internal CatalogПростые преобразования, которые всегда должны читать актуальные исходные данные
tableПолностью перестраиваемая таблица Duplicate Key в Internal Catalog или таблица Iceberg с поддержкой записиРезультаты ограниченного объема, для которых нужна стабильная производительность запросов
incrementalДобавляет, обновляет или перезаписывает данные в соответствии со стратегиейИнкрементальная обработка больших таблиц
materialized_viewАсинхронное материализованное представление Doris в Internal CatalogОбновление под управлением Doris и прозрачное переписывание запросов
ephemeralКомпилируется в CTE в зависимых моделяхПовторное использование SQL без создания объекта Doris

Seed и снимки также могут создавать таблицы Doris. В настоящее время адаптер не включает отдельную материализацию partition; для замены партиций используйте инкрементальную стратегию insert_overwrite. В приведенных ниже примерах сохраняется replication_num=1, чтобы они также работали в кластере разработки с одним BE; в реальных развертываниях используйте количество реплик, подходящее для промышленной среды.

Представление​

{{ config(materialized='view') }}

select order_id, customer_id, amount
from {{ source('raw', 'orders') }}
where status = 'PAID'

Каждый запуск обновляет определение представления. Представление не хранит данные; стоимость запроса зависит от SQL представления и запроса, который его использует.

Таблица​

{{
config(
materialized='table',
duplicate_key=['event_date', 'event_id'],
partition_by=['event_date'],
partition_type='RANGE',
partition_by_init=[
"PARTITION p_before_202608 VALUES LESS THAN ('2026-08-01')",
"PARTITION p202608 VALUES LESS THAN ('2026-09-01')",
"PARTITION pmax VALUES LESS THAN (MAXVALUE)"
],
distributed_by=['event_id'],
buckets=16,
properties={'replication_num': '1'}
)
}}

select
cast(order_time as date) as event_date,
order_id as event_id,
status as event_type
from {{ source('raw', 'orders') }}

Для целевых объектов в Internal Catalog материализация table создает таблицу Duplicate Key и полностью заменяет ее при последующих запусках. Целевые таблицы Iceberg не используют ключи Doris OLAP или распределение по умолчанию. Модели таблиц принимают следующие параметры создания таблицы:

ПараметрТип и значение по умолчаниюОписание
duplicate_keyСтрока или список; необязательныйСтолбцы Duplicate Key
partition_byСтрока или список; необязательныйСтолбцы партиционирования
partition_typeRANGE или LIST; по умолчанию RANGEТип партиционирования, используемый с partition_by
partition_by_initСписок строк; необязательныйОпределения партиций Doris, используемые с partition_by при создании таблицы
distributed_byСтрока или список; необязательныйСтолбцы хеш-распределения
bucketsПоложительное целое число; по умолчанию 10, если формируется Hash DistributionКоличество хеш-бакетов; используется только с distributed_by
replication_numПоложительное целое число или строка с числом; необязательныйКоличество реплик; параметр верхнего уровня переопределяет одноименный ключ в properties
propertiesСловарь; необязательныйПары «ключ-значение», включаемые в Doris PROPERTIES

Столбцы Duplicate Key, партиционирования и распределения должны присутствовать в результате модели и соответствовать правилам создания таблиц Doris. Адаптер включает partition_by_init и properties в оператор CREATE TABLE; Doris проверяет определения партиций, имена и значения свойств. Специфичные для OLAP параметры, такие как duplicate_key и distributed_by, не подходят для целевых таблиц Iceberg. Обычная модель table в настоящее время не предоставляет настройки Aggregate Key или отдельной конфигурации Unique Key. Для вставки и обновления по Unique Key используйте инкрементальную стратегию merge.

Инкрементальная материализация​

Для стратегий append, merge и insert_overwrite инкрементальная модель состоит из двух частей:

  • SQL модели, обычно с is_incremental(), определяет, какие строки источника возвращает текущий запуск.
  • incremental_strategy определяет, как адаптер записывает эту порцию данных в целевой объект.

Microbatch не использует такой способ фильтрации. dbt Core добавляет временные фильтры на основе контекста порции и параметра event_time, настроенного для вышестоящих ресурсов.

СтратегияЦелевой объект Doris и поведениеОсновные требования
appendINSERT INTO в таблицу OLAP Duplicate Key или таблицу Iceberg с поддержкой записиНе задавайте unique_key
mergeВставка или обновление полной строки через INSERT INTO в таблице OLAP Unique Key; нативный MERGE INTO в IcebergТребует unique_key; для Iceberg также нужны нативная поддержка MERGE и таблицы V2+
insert_overwriteДля OLAP: перезапись всей таблицы, именованных или динамически определяемых партиций; для Iceberg: перезапись всей таблицы, динамических или статических партицийОтклоняет unique_key; статическая область в Iceberg задается сопоставлением столбцов и значений
microbatchДля OLAP: перезапись строго соответствующей RANGE-партиции; для Iceberg: замена одного окна UTC с помощью нативного MERGEНастройте event_time, batch_size и begin; для Iceberg требуются нативный MERGE и V2+

Если стратегия не задана, наличие unique_key выбирает merge; иначе адаптер использует append. Адаптер поддерживает все четыре режима on_schema_change: ignore, fail, append_new_columns и sync_all_columns.

Стратегии delete+insert и delete_insert отклоняются. Для вставки и обновления по Doris Unique Key используйте merge. Для целевых объектов OLAP стратегия merge использует INSERT INTO для полной строки с семантикой Doris Unique Key. Для целевых объектов Iceberg она формирует нативный MERGE INTO и отклоняет дублирующиеся ключи источника до записи. Каждая порция должна содержать не более одной строки для каждого unique_key. Чтобы использовать Sequence Column, задайте видимый столбец через function_column.sequence_col в properties и продолжайте использовать merge. Отдельный параметр sequence_col и параметр function_column.sequence_type со скрытым столбцом __DORIS_SEQUENCE_COL__ в настоящее время не поддерживаются.

В следующем примере выполняется вставка или обновление полной строки по order_id:

{{
config(
materialized='incremental',
incremental_strategy='merge',
unique_key=['order_id'],
distributed_by=['order_id'],
buckets=16,
properties={'replication_num': '1'},
on_schema_change='append_new_columns'
)
}}

select
order_id,
customer_id,
amount,
updated_at
from {{ source('raw', 'orders') }}

{% if is_incremental() %}
where updated_at >= (
select coalesce(max(updated_at), '1970-01-01 00:00:00')
from {{ this }}
)
{% endif %}

Чтобы перезаписать именованные партиции Doris в Internal Catalog:

{{
config(
materialized='incremental',
incremental_strategy='insert_overwrite',
duplicate_key=['event_date', 'event_id'],
partition_by=['event_date'],
partition_type='RANGE',
partition_by_init=[
"PARTITION p_before_202607 VALUES LESS THAN ('2026-07-01')",
"PARTITION p202607 VALUES LESS THAN ('2026-08-01')",
"PARTITION p202608 VALUES LESS THAN ('2026-09-01')",
"PARTITION pmax VALUES LESS THAN (MAXVALUE)"
],
overwrite_partitions=['p202607', 'p202608'],
distributed_by=['event_id'],
buckets=16,
properties={'replication_num': '1'}
)
}}

select event_date, event_id, event_type
from (
select
cast(order_time as date) as event_date,
order_id as event_id,
status as event_type,
order_time
from {{ source('raw', 'orders') }}
) events

{% if is_incremental() %}
where order_time >= '2026-07-01'
and order_time < '2026-09-01'
{% endif %}

Первый запуск создает целевую таблицу через CTAS и не выполняет INSERT OVERWRITE. Поэтому в примере используется partition_by_init для создания всех необходимых целевых партиций. После создания целевой таблицы параметр overwrite_partitions управляет областью перезаписи:

  • Не задан: перезаписывается вся таблица.
  • Список имен партиций: перезаписываются только эти партиции.
  • '*': Doris динамически перезаписывает партиции, затронутые порцией данных.

Динамическая перезапись OLAP не может определить, какую партицию очистить, если порция данных пуста. Укажите имена партиций, если пустая порция исходных данных должна очищать целевые данные.

Для целевых таблиц Iceberg не задавайте overwrite_partitions, чтобы использовать нативную динамическую перезапись партиционированных таблиц. Чтобы заменить одну статическую область, задайте непустое сопоставление столбцов и значений, например overwrite_partitions={'dt': '2025-01-25'}. Модель должна возвращать все строки в этой области. Для непартиционированной целевой таблицы модель должна возвращать полный результат для замены; пустой результат очищает таблицу. Пустой результат для статической области также очищает эту область. Сопоставление, содержащее NULL, использует нативный MERGE и требует Iceberg V2+.

Microbatch​

microbatch использует контекст порции данных dbt Core. Следующий пример предназначен для таблицы OLAP в Internal Catalog и перезаписывает одну точно соответствующую RANGE-партицию для каждого окна UTC. Настройте поле event_time для каждого непосредственного вышестоящего ресурса и для целевой модели. Для источника raw.orders, созданного выше в примере первой модели, добавьте следующую конфигурацию в существующее объявление таблицы:

sources:
- name: raw
schema: raw
tables:
- name: orders
config:
event_time: order_time
{{
config(
materialized='incremental',
incremental_strategy='microbatch',
event_time='event_time',
batch_size='day',
begin=modules.datetime.datetime(2026, 8, 1, 0, 0, 0),
duplicate_key=['event_id', 'event_time'],
partition_by=['event_time'],
partition_type='RANGE',
distributed_by=['event_id'],
buckets=16,
properties={'replication_num': '1'}
)
}}

select
order_id as event_id,
order_time as event_time,
status as event_type
from {{ source('raw', 'orders') }}

Для целевой таблицы OLAP в Internal Catalog параметр event_time должен быть именем столбца без кавычек и указывать на тот же единственный столбец, что и partition_by. Параметр batch_size поддерживает hour, day, month и year. Целевая таблица относится к типу Duplicate Key: duplicate_key задает ключ таблицы Doris и не является dbt unique_key. Не задавайте unique_key, overwrite_partitions или partition_by_init; адаптер определяет границы партиции и целевой объект перезаписи по текущей порции данных. Если вышестоящий ref() или source() также настраивает event_time, dbt Core фильтрует эти входные данные по текущему окну. Порции Microbatch выполняются последовательно и перезаписывают точно соответствующую партицию даже при пустой порции, поэтому строки, удаленные из этого окна, очищаются.

Microbatch в Internal Catalog также может использовать Doris Dynamic Partition, если настроены следующие свойства и они проходят проверку адаптера:

  • dynamic_partition.enable='true'.
  • dynamic_partition.time_unit соответствует batch_size, а dynamic_partition.time_zone равен UTC, Etc/UTC или +00:00.
  • dynamic_partition.create_history_partition='true' вместе с dynamic_partition.start или dynamic_partition.history_partition_num.
  • dynamic_partition.prefix является допустимым идентификатором, а dynamic_partition.end является положительным целым числом.
  • Для месячных порций параметр dynamic_partition.start_day_of_month, если он задан, равен 1.

При создании таблицы Dynamic Partition Doris также требует положительного значения dynamic_partition.buckets; это свойство проверяет Doris, а не адаптер. Окно хранения должно охватывать begin, lookback и любой диапазон ручного заполнения историческими данными. Для существующего целевого объекта физические свойства, проверяемые адаптером, должны соответствовать конфигурации модели; иначе приведите конфигурацию в соответствие или выполните запуск с --full-refresh.

предупреждение

Для append, merge и insert_overwrite в пределах партиций адаптер не обнаруживает новые или измененные строки источника автоматически. SQL модели должен возвращать нужную порцию данных. При перезаписи всей таблицы через insert_overwrite модель должна возвращать все целевые данные. Каждая порция merge должна содержать уникальные значения unique_key. dbt Core обеспечивает фильтрацию Microbatch по вышестоящим ресурсам с настроенным event_time, поэтому моделям Microbatch не нужен is_incremental(). После несовместимых изменений ключей, партиционирования или физического размещения данных выполните dbt run --full-refresh. Для Iceberg Microbatch не задавайте unique_key, overwrite_partitions (включая сопоставления столбцов и значений), partition_by_init и свойства OLAP Dynamic Partition. Если настроен partition_by, задайте partition_type='LIST'. Каждое окно UTC заменяется с помощью нативного MERGE, включая пустые окна.

Асинхронные материализованные представления​

Пользователи dbt задают стандартную настройку materialized='materialized_view'. Адаптер реализует ее с помощью асинхронного материализованного представления Doris.

примечание

Проверка версии FE для этой материализации допускает Doris 2.x начиная с 2.1.5, Doris 3.x кроме 3.0.0, Doris 4.x и новее, а также идентифицируемые сборки из исходного кода, сообщающие версию в виде doris-0.0.0-<git-sha>. Сборки из исходного кода предназначены только для тестирования при разработке. Эти проверки являются условиями допуска в коде, а не подтверждением того, что каждая допускаемая версия прошла тестирование совместимости.

{{
config(
materialized='materialized_view',
build_mode='immediate',
refresh_method='auto',
refresh_trigger='manual',
duplicate_key=['order_date'],
distribution_type='hash',
distributed_by=['order_date'],
buckets=8,
wait_for_refresh=true,
properties={'replication_num': '1'}
)
}}

select order_date, sales_amount
from {{ ref('fct_daily_sales') }}
ПараметрЗначение по умолчаниюПоддерживаемые значения или формат
build_modeimmediateimmediate, deferred
refresh_methodautoauto позволяет Doris определять область обновления; complete обновляет все партиции
refresh_triggermanualmanual, schedule, commit
refresh_schedule-Обязателен для schedule; содержит положительный interval, единицу измерения minute/hour/day/week и необязательный start_time
wait_for_refreshtrueОжидать ли первоначального построения BUILD IMMEDIATE или ручного обновления, запущенного адаптером
refresh_wait_timeout300Время ожидания задачи обновления в секундах; положительное целое число
refresh_poll_interval1Интервал опроса задачи обновления в секундах; положительное целое число, не превышающее время ожидания
duplicate_key-Столбцы Duplicate Key для асинхронного материализованного представления; строка или список
partition_by-Один столбец партиционирования Doris или выражение функции партиционирования; строка или список из одного элемента
distribution_typeВыбирается автоматическиhash, если задан distributed_by; иначе random
distributed_by-Столбцы Hash Distribution
bucketsautoПоложительное целое число или auto
replication_num-Удобный параметр для задания количества реплик; переопределяет одноименный ключ в properties
properties{}Свойства асинхронного материализованного представления Doris
on_configuration_changeapplyapply, continue, fail

BUILD IMMEDIATE запускает первоначальное построение при создании или замене определения. Адаптер создает новое определение под временным именем, по умолчанию ожидает первоначального построения, а затем публикует его под целевым именем; дополнительный REFRESH MATERIALIZED VIEW не отправляется. BUILD DEFERRED создает определение без первоначального построения.

Если определение не изменилось, поведение обновления полностью определяется refresh_trigger; параметр refresh_on_run в настоящее время отсутствует:

  • manual отправляет REFRESH MATERIALIZED VIEW ... AUTO|COMPLETE, когда последующий dbt run выбирает модель, и по умолчанию ожидает успешного завершения.
  • schedule и commit не отправляют запрос на обновление при последующем запуске dbt; Doris запускает его по расписанию или при фиксации изменений в базовой таблице.

Например, настройте ежедневное расписание следующим образом:

{{
config(
materialized='materialized_view',
build_mode='deferred',
refresh_method='auto',
refresh_trigger='schedule',
refresh_schedule={
'interval': 1,
'unit': 'day'
},
properties={'replication_num': '1'}
)
}}

select order_date, sales_amount
from {{ ref('fct_daily_sales') }}

wait_for_refresh=false отключает опрос задачи, но не отменяет отправку запроса на обновление. Истечение времени ожидания в dbt не отменяет уже отправленную задачу Doris. Адаптер определяет новую отправленную задачу, сравнивая идентификаторы задач Doris MV до и после отправки, поэтому избегайте одновременных ручных обновлений одного и того же целевого объекта.

При изменении SQL модели или конфигурации DDL значение по умолчанию on_configuration_change=apply создает временное асинхронное материализованное представление и атомарно заменяет существующее определение. continue сохраняет существующее определение без отправки запроса на ручное обновление, а fail останавливает выполнение. --full-refresh принудительно развертывает определение заново.

Другие возможности dbt​

ВозможностьПоддержка
SeedПоместите небольшие CSV-файлы, хранящиеся в системе контроля версий, в seeds/, затем выполните dbt seed; поддерживаются определение типов, column_types и ref
SnapshotОпределите стратегии check или timestamp в snapshots/, затем выполните dbt snapshot; поддерживаются физическое удаление и эволюция схемы. Замена в Internal Catalog атомарна; замена в Iceberg использует резервную копию и переименование
Тесты данныхНастройте Generic Tests в YAML или напишите Singular Tests в tests/; поддерживаются сценарии ephemeral и store_failures
Модульные тестыЗадайте тестовые данные в виде встроенных строк или CSV в YAML модели, затем выполните dbt test --select test_type:unit
Контракты моделейЗадайте contract.enforced: true и объявите имена и типы столбцов для моделей Table, View или Incremental; объявления constraints отклоняются, а тесты данных не создают ограничений базы данных
Сохранение документацииВключите persist_docs для сохранения комментариев к объектам и столбцам для основных типов объектов
Актуальность источниковНастройте loaded_at_field или loaded_at_query вместе с freshness, затем выполните dbt source freshness
Права доступаИспользуйте стандартную конфигурацию grants для прав на таблицы пользователей Doris user и user@host; роли в качестве получателей прав в настоящее время не поддерживаются
ХукиИспользуйте pre_hook и post_hook для выполнения SQL Doris до и после материализаций; побочные эффекты хуков не откатываются транзакционно
Документация и происхождение данныхНапишите описания и выполните dbt docs generate для получения метаданных объектов и столбцов Internal Catalog и External Catalog, включая асинхронные материализованные представления Internal Catalog

Seed подходят для небольших данных, хранящихся в системе контроля версий, например кодов стран или сопоставлений статусов, а не для массовой загрузки бизнес-данных. Для больших файлов используйте Doris Stream Load, Broker Load или Doris Connector.

Значения unique_key в источнике Snapshot не должны быть NULL и должны быть уникальными в пределах каждой порции. При использовании стратегии timestamp значение updated_at не должно быть NULL и не может предшествовать текущей исторической версии для этого ключа.

Чтобы сохранять описания таблиц и столбцов:

models:
- name: fct_daily_sales
description: Daily sales summary
config:
persist_docs:
relation: true
columns: true
columns:
- name: order_date
description: Order date
- name: sales_amount
description: Daily sales amount

Актуальность источников​

Проверка актуальности источников поддерживает два способа явного задания временной метки. Для обычного случая со столбцом временных меток используйте loaded_at_field:

sources:
- name: raw
schema: raw
tables:
- name: orders
config:
loaded_at_field: updated_at
freshness:
warn_after: {count: 1, period: hour}
error_after: {count: 2, period: hour}

Используйте loaded_at_query, если для получения временной метки актуальности нужен собственный SQL или агрегация:

sources:
- name: raw
schema: raw
tables:
- name: orders
config:
loaded_at_query: |
select max(updated_at)
from {{ this }}
where is_valid = 1
freshness:
warn_after: {count: 1, period: hour}
error_after: {count: 2, period: hour}

При использовании loaded_at_field задайте filter внутри freshness, например filter: is_valid = 1, чтобы ограничить строки, участвующие в оценке актуальности. Не задавайте loaded_at_field и loaded_at_query одновременно. В настоящее время адаптер не определяет время загрузки по метаданным таблицы Doris; явно укажите поле или запрос.

Адаптер использует utc_timestamp() в качестве текущего времени, следуя принятому в dbt Core правилу: временные метки актуальности без часового пояса интерпретируются как UTC.

Права доступа​

При декларативном назначении прав получателями выступают пользователи Doris:

models:
doris_demo:
+grants:
select:
- analyst
- reporter@10.0.0.%

Имя без @host интерпретируется как username@%. Права сопоставляются следующим образом: select с SELECT_PRIV, insert с LOAD_PRIV, alter с ALTER_PRIV, create с CREATE_PRIV, drop с DROP_PRIV и show_view с SHOW_VIEW_PRIV. Роли Doris в настоящее время не поддерживаются в grants; указывайте конкретных пользователей. Учетная запись, от имени которой запускается dbt, должна иметь возможность просматривать получателей прав и изменять права на целевые объекты.

Основные команды​

КомандаНазначение
dbt debugПроверить конфигурацию проекта и подключение к Doris
dbt parseРазобрать проект без выполнения SQL
dbt compileСкомпилировать модели и проверить сгенерированный SQL для Doris
dbt runПостроить выбранные модели
dbt testВыполнить тесты данных и модульные тесты
dbt buildВыполнить Seed, модели, снимки и тесты в порядке зависимостей
dbt seedЗагрузить CSV-файлы Seed
dbt snapshotОбновить снимки
dbt source freshnessОценить актуальность источников
dbt docs generateСгенерировать метаданные каталога, документации и происхождения данных

Распространенные селекторы:

# Run one model
dbt run --select fct_daily_sales

# Run the model and all upstream dependencies
dbt build --select +fct_daily_sales

# Run the model and all downstream dependencies
dbt build --select fct_daily_sales+

# Fully rebuild an incremental model
dbt run --select fct_orders --full-refresh

Текущие ограничения​

  • В настоящее время адаптер не поддерживает моделирование таблиц Aggregate Key и настройку вторичных индексов.
  • Поведение записи в External Catalog зависит от коннектора Doris. Catalogs V2 и гарантии записи, специфичные для отдельных коннекторов, не поддерживаются.
  • В настоящее время адаптер не реализует настройку SSL, тайм-ауты и повторные попытки, переключение при отказе между несколькими FE, отмену на стороне сервера и полную телеметрию запросов.
  • При некоторых изменениях типов Table/View/MV каноническое имя на короткое время становится недоступным, поэтому переключение происходит с кратким перерывом в доступности.

Устранение неполадок​

dbt debug не удается подключиться​

Убедитесь, что host и port указывают на доступный порт запросов MySQL процесса FE, и проверьте имя пользователя, пароль и сетевую политику. Порт запросов по умолчанию: 9030; 8030 обычно является HTTP-портом FE.

Catalog или база данных не найдены​

В v1.1.1 значения database в профиле и источниках указывают на Doris Catalog, а schema обозначает базу данных внутри него. Для Internal Catalog не задавайте database. Если в старом проекте параметр database источника использовался для базы данных Doris, перенесите это значение в schema. Проверьте, что внешние Catalog уже существуют и видны учетной записи dbt.