Перейти к основному содержанию
Перейти к основному содержанию

Возможности и конфигурации

ClickHouse Supported

В этом разделе описаны некоторые функции dbt при работе с ClickHouse.

Конфигурация Profile.yml

Чтобы подключиться к ClickHouse из dbt, вам потребуется добавить профиль в файл profiles.yml. Профиль ClickHouse должен соответствовать следующему синтаксису:

your_profile_name:
  target: dev
  outputs:
    dev:
      type: clickhouse

      # Optional
      schema: [default] # База данных ClickHouse для моделей dbt
      driver: [http] # http или native. Если не указано, определяется автоматически на основе настройки порта
      host: [localhost] 
      port: [8123]  # Если не указано, по умолчанию используется 8123, 8443, 9000 или 9440 в зависимости от настроек secure и driver 
      user: [default] # Пользователь для всех операций с базой данных
      password: [<empty string>] # Пароль пользователя
      cluster: [<empty string>] # Если указано, определённые DDL-операции и операции с таблицами будут выполняться с конструкцией `ON CLUSTER` для данного кластера. Распределённые материализации требуют этой настройки. Подробнее см. раздел о кластере ClickHouse ниже.
      verify: [True] # Проверять TLS-сертификат при использовании TLS/SSL
      secure: [False] # Использовать TLS (нативный протокол) или HTTPS (протокол http)
      client_cert: [null] # Путь к клиентскому TLS-сертификату в формате .pem
      client_cert_key: [null] # Путь к закрытому ключу клиентского TLS-сертификата
      retries: [1] # Количество повторных попыток при возникновении повторяемого исключения базы данных (например, ошибки 503 'Service Unavailable')
      compression: [<empty string>] # Использовать сжатие gzip, если указано (http), или тип сжатия для нативного соединения
      connect_timeout: [10] # Тайм-аут в секундах для установления соединения с ClickHouse
      send_receive_timeout: [300] # Тайм-аут в секундах для получения данных от сервера ClickHouse
      cluster_mode: [False] # Использовать специальные настройки для улучшения работы с реплицируемыми базами данных (рекомендуется для ClickHouse Cloud)
      use_lw_deletes: [False] # Использовать стратегию `delete+insert` в качестве инкрементной стратегии по умолчанию.
      check_exchange: [True] # Проверить, что ClickHouse поддерживает атомарную команду EXCHANGE TABLES. (Не требуется для большинства версий ClickHouse)
      local_suffix: [_local] # Суффикс локальных таблиц на шардах для распределённых материализаций.
      local_db_prefix: [<empty string>] # Префикс базы данных для локальных таблиц на шардах при распределённых материализациях. Если не указано, используется та же база данных, что и для распределённой таблицы.
      allow_automatic_deduplication: [False] # Включить автоматическую дедупликацию ClickHouse для реплицируемых таблиц
      tcp_keepalive: [False] # Только для нативного клиента, задаёт конфигурацию TCP keepalive. Укажите пользовательские настройки keepalive в формате [idle_time_sec, interval_sec, probes].
      custom_settings: [{}] # Словарь пользовательских настроек ClickHouse для соединения — по умолчанию пустой.
      database_engine: '' # Движок базы данных для создания новых схем (баз данных) ClickHouse. Если не указано (по умолчанию), новые базы данных будут использовать движок базы данных ClickHouse по умолчанию (обычно Atomic).
      threads: [1] # Количество потоков для выполнения запросов. Перед установкой значения больше 1 обязательно прочитайте раздел [согласованность чтения после записи](#read-after-write-consistency).
      
      # Настройки нативного соединения (clickhouse-driver)
      sync_request_timeout: [5] # Тайм-аут для проверки связи с сервером
      compress_block_size: [1048576] # Размер блока сжатия, если сжатие включено

Схема и база данных

Идентификатор отношения модели dbt database.schema.table не совместим с ClickHouse, поскольку ClickHouse не поддерживает schema. Поэтому используется упрощённый вариант schema.table, где schema — это база данных ClickHouse. Использование базы данных default не рекомендуется.

Предупреждение об операторе SET

Во многих средах использование оператора SET для сохранения настройки ClickHouse, применяемой ко всем запросам dbt, ненадёжно и может приводить к неожиданным сбоям. Это особенно актуально при использовании HTTP‑подключений через балансировщик нагрузки, который распределяет запросы между несколькими узлами (например, ClickHouse Cloud), хотя в некоторых случаях это может происходить и с нативными подключениями к ClickHouse. Соответственно, мы рекомендуем настраивать все необходимые параметры ClickHouse в свойстве "custom_settings" профиля dbt как рекомендуемую практику, вместо того чтобы полагаться на оператор "SET" в pre-hook, как иногда предлагается.

Настройка quote_columns

Чтобы избежать предупреждения, обязательно явно задайте значение параметра quote_columns в файле dbt_project.yml. Дополнительную информацию смотрите в документации по quote_columns.

seeds:
  +quote_columns: false  #или `true`, если в заголовках столбцов CSV есть пробелы

О кластере ClickHouse

При использовании кластера ClickHouse нужно учитывать две вещи:

  • Установку настройки cluster.
  • Обеспечение согласованности чтения после записи (read-after-write), особенно если вы используете более одного потока (threads).

Настройка кластера

Настройка cluster в профиле позволяет dbt-clickhouse работать с кластером ClickHouse. Если cluster задан в профиле, по умолчанию все модели будут создаваться с оператором ON CLUSTER, за исключением моделей, использующих движок Replicated. К ним относятся:

  • создание баз данных,
  • материализации представлений,
  • табличные и инкрементальные материализации,
  • распределённые материализации.

Движки Replicated не будут включать оператор ON CLUSTER, так как они изначально предназначены для внутреннего управления репликацией.

Чтобы отключить создание на кластере для конкретной модели, добавьте конфигурацию disable_on_cluster:

{{ config(
        engine='MergeTree',
        materialized='table',
        disable_on_cluster='true'
    )
}}

табличные и инкрементальные материализации с нереплицируемым движком не будут затронуты настройкой cluster (модель будет создана только на подключённом узле).

Совместимость

Если модель была создана без настройки cluster, dbt-clickhouse обнаружит это и выполнит все DDL/DML без предложения on cluster для этой модели.

Согласованность чтения после записи (read-after-write)

dbt полагается на модель согласованности чтения после вставки (read-after-insert). Это несовместимо с кластерами ClickHouse с более чем одной репликой, если вы не можете гарантировать, что все операции будут направляться на одну и ту же реплику. В повседневной работе с dbt вы можете не столкнуться с проблемами, но в зависимости от конфигурации кластера есть несколько стратегий, позволяющих обеспечить такую гарантию:

  • Если вы используете кластер ClickHouse Cloud, вам достаточно установить select_sequential_consistency: 1 в свойстве custom_settings вашего профиля. Дополнительную информацию об этой настройке можно найти здесь.
  • Если вы используете кластер с самостоятельным размещением (self-hosted), убедитесь, что все запросы dbt отправляются на одну и ту же реплику ClickHouse. Если поверх него есть балансировщик нагрузки, попробуйте использовать механизм replica aware routing/sticky sessions, чтобы всегда попадать на одну и ту же реплику. Добавление настройки select_sequential_consistency = 1 в кластерах вне ClickHouse Cloud не рекомендуется.

Общая информация о возможностях

Общие конфигурации таблиц

OptionDescriptionDefault if any
engineДвижок таблицы (тип таблицы), который используется при создании таблицMergeTree()
order_byКортеж имён столбцов или произвольных выражений. Это позволяет создать небольшой разреженный индекс, который помогает быстрее находить данные.tuple()
partition_byПартиция — это логическое объединение записей в таблице по заданному критерию. Ключ партиционирования может быть любым выражением из столбцов таблицы.
sharding_keyКлюч шардирования определяет целевой сервер при вставке в таблицу с распределённым движком. Ключ шардирования может быть случайным или представлять собой результат хеш-функцииrand())
primary_keyКак и order_by, выражение первичного ключа ClickHouse. Если не указано, ClickHouse использует выражение ORDER BY в качестве первичного ключа
unique_keyКортеж имён столбцов, которые однозначно идентифицируют строки. Используется с инкрементальными моделями для обновлений.
settingsОтображение/словарь настроек уровня "TABLE", которые будут использоваться в DDL-выражениях, таких как 'CREATE TABLE', для этой модели
query_settingsОтображение/словарь пользовательских настроек ClickHouse, которые будут использоваться с выражениями INSERT или DELETE в сочетании с этой моделью
ttlВыражение TTL, которое будет использоваться с таблицей. Выражение TTL — это строка, задающая время жизни (TTL) для таблицы.
indexesСписок data skipping индексов для создания. Дополнительная информация приведена ниже.
sql_securityПозволяет указать, какого пользователя ClickHouse использовать при выполнении базового запроса представления. SQL SECURITY принимает два допустимых значения: definer, invoker.
definerЕсли sql_security установлено в значение definer, необходимо указать любого существующего пользователя или CURRENT_USER в предложении definer.
projectionsСписок проекций, которые будут созданы. Подробности см. в разделе О проекциях.

О data skipping индексах

Data skipping индексы доступны только для материализации table. Чтобы добавить список data skipping индексов в таблицу, используйте конфигурацию indexes:

{{ config(
        materialized='table',
        indexes=[{
          'name': 'your_index_name',
          'definition': 'your_column TYPE minmax GRANULARITY 2'
        }]
) }}

О проекциях

Вы можете добавить проекции к материализациям типов table и distributed_table с помощью конфигурации projections:

{{ config(
       materialized='table',
       projections=[
           {
               'name': 'your_projection_name',
               'query': 'SELECT department, avg(age) AS avg_age GROUP BY department'
           }
       ]
) }}

Примечание: Для распределённых таблиц проекция применяется к таблицам _local, а не к распределённой прокси-таблице.

Поддерживаемые движки таблиц

ТипПодробности
MergeTree (по умолчанию)https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/
HDFShttps://clickhouse.com/docs/en/engines/table-engines/integrations/hdfs
MaterializedPostgreSQLhttps://clickhouse.com/docs/en/engines/table-engines/integrations/materialized-postgresql
S3https://clickhouse.com/docs/en/engines/table-engines/integrations/s3
EmbeddedRocksDBhttps://clickhouse.com/docs/en/engines/table-engines/integrations/embedded-rocksdb
Hivehttps://clickhouse.com/docs/en/engines/table-engines/integrations/hive

Поддерживаемые экспериментальные движки таблиц

ТипПодробности
Distributed Tablehttps://clickhouse.com/docs/en/engines/table-engines/special/distributed.
Dictionaryhttps://clickhouse.com/docs/en/engines/table-engines/special/dictionary

Если вы столкнётесь с проблемами при подключении к ClickHouse из dbt с одним из вышеуказанных движков, пожалуйста, сообщите о проблеме здесь.

Примечание о настройках моделей

В ClickHouse есть несколько типов/уровней «настроек». В конфигурации модели выше настраиваются два их типа. settings означает секцию SETTINGS, используемую в DDL-операторах вида CREATE TABLE/VIEW, то есть, как правило, это настройки, специфичные для конкретного табличного движка ClickHouse. Новый query_settings используется для добавления секции SETTINGS к запросам INSERT и DELETE, применяемым для материализации моделей (включая инкрементальные материализации). Существуют сотни настроек ClickHouse, и не всегда ясно, какая является настройкой «таблицы», а какая — настройкой «пользователя» (хотя последние, как правило, доступны в таблице system.settings). В целом рекомендуются настройки по умолчанию, а любое использование этих свойств следует тщательно исследовать и протестировать.

Конфигурация столбцов

ПРИМЕЧАНИЕ: Приведённые ниже параметры конфигурации столбцов требуют применения контрактов моделей.

ПараметрОписаниеЗначение по умолчанию
codecСтрока, состоящая из аргументов, передаваемых в CODEC() в DDL-описании столбца. Например: codec: "Delta, ZSTD" будет скомпилирована в выражение CODEC(Delta, ZSTD).
ttlСтрока, состоящая из TTL-выражения (time-to-live), которое определяет TTL-правило в DDL-описании столбца. Например: ttl: ts + INTERVAL 1 DAY будет скомпилирована в выражение TTL ts + INTERVAL 1 DAY.

Пример конфигурации схемы

models:
  - name: table_column_configs
    description: 'Тестирование конфигураций на уровне колонок'
    config:
      contract:
        enforced: true
    columns:
      - name: ts
        data_type: timestamp
        codec: ZSTD
      - name: x
        data_type: UInt8
        ttl: ts + INTERVAL 1 DAY

Добавление сложных типов данных

dbt автоматически определяет тип данных каждого столбца, анализируя SQL, используемый для создания модели. Однако в некоторых случаях этот процесс может некорректно определить тип данных, что приводит к конфликтам с типами, указанными в свойстве контракта data_type. Чтобы избежать этого, рекомендуется использовать функцию CAST() в SQL-коде модели для явного указания требуемого типа. Например:

{{
    config(
        materialized="materialized_view",
        engine="AggregatingMergeTree",
        order_by=["event_type"],
    )
}}

select
  -- event_type может быть выведен как String, но предпочтительнее использовать LowCardinality(String):
  CAST(event_type, 'LowCardinality(String)') as event_type,
  -- countState() может быть выведен как `AggregateFunction(count)`, но предпочтительнее изменить тип используемого аргумента:
  CAST(countState(), 'AggregateFunction(count, UInt32)') as response_count, 
  -- maxSimpleState() может быть выведен как `SimpleAggregateFunction(max, String)`, но предпочтительнее также изменить тип используемого аргумента:
  CAST(maxSimpleState(event_type), 'SimpleAggregateFunction(max, LowCardinality(String))') as max_event_type
from {{ ref('user_events') }}
group by event_type

Возможности

Материализация: view

Модель dbt может быть создана как представление ClickHouse и настроена с использованием следующего синтаксиса:

Файл проекта (dbt_project.yml):

models:
  <resource-path>:
    +materialized: view

Или конфигурационный блок (models/<model_name>.sql):

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

Материализация: таблица

Модель dbt может быть создана как таблица ClickHouse и настроена с использованием следующего синтаксиса:

Файл проекта (dbt_project.yml):

models:
  <resource-path>:
    +materialized: table
    +order_by: [ <column-name>, ... ]
    +engine: <engine-type>
    +partition_by: [ <column-name>, ... ]

Или конфигурационный блок (models/<model_name>.sql):

{{ config(
    materialized = "table",
    engine = "<тип-движка>",
    order_by = [ "<имя-столбца>", ... ],
    partition_by = [ "<имя-столбца>", ... ],
      ...
    ]
) }}

Материализация: incremental

Модель таблицы будет пересоздаваться при каждом выполнении dbt. Это может быть неосуществимо и крайне затратно для больших наборов данных или сложных трансформаций. Чтобы решить эту проблему и сократить время сборки, модель dbt может быть создана как инкрементальная таблица ClickHouse и настраивается с помощью следующего синтаксиса:

Определение модели в dbt_project.yml:

models:
  <resource-path>:
    +materialized: incremental
    +order_by: [ <column-name>, ... ]
    +engine: <engine-type>
    +partition_by: [ <column-name>, ... ]
    +unique_key: [ <column-name>, ... ]
    +inserts_only: [ True|False ]

Или конфигурационный блок в models/&lt;model_name&gt;.sql:

{{ config(
    materialized = "incremental",
    engine = "<тип-движка>",
    order_by = [ "<имя-столбца>", ... ],
    partition_by = [ "<имя-столбца>", ... ],
    unique_key = [ "<имя-столбца>", ... ],
    inserts_only = [ True|False ],
      ...
    ]
) }}

Конфигурации

Конфигурации, специфические для этого типа материализации, перечислены ниже:

OptionDescriptionRequired?
unique_keyКортеж имён столбцов, которые однозначно идентифицируют строки. Подробности об ограничениях уникальности см. здесь.Обязателен. Если не указано, изменённые строки будут добавлены в инкрементальную таблицу дважды.
inserts_onlyПараметр устарел в пользу инкрементальной strategy append, которая работает аналогичным образом. Если для инкрементальной модели установлено значение True, инкрементальные обновления будут вставляться напрямую в целевую таблицу без создания промежуточной таблицы. Если задан inserts_only, incremental_strategy игнорируется.Необязателен (по умолчанию: False)
incremental_strategyСтратегия, используемая для инкрементальной материализации. Поддерживаются delete+insert, append, insert_overwrite или microbatch. Дополнительные сведения о стратегиях см. здесь.Необязателен (по умолчанию: 'default')
incremental_predicatesДополнительные условия, которые будут применяться к инкрементальной материализации (применяются только для стратегии delete+insert).Необязателен

Стратегии инкрементальных моделей

dbt-clickhouse поддерживает три стратегии инкрементальных моделей.

Стратегия по умолчанию (устаревшая)

Исторически ClickHouse имел лишь ограниченную поддержку операций обновления и удаления в форме асинхронных «мутаций». Чтобы эмулировать ожидаемое поведение dbt, dbt-clickhouse по умолчанию создаёт новую временную таблицу, содержащую все незатронутые (не удалённые, не изменённые) «старые» записи, а также все новые или обновлённые записи, а затем заменяет этой временной таблицей существующее инкрементальное relation модели. Это единственная стратегия, которая сохраняет исходное relation, если что-то идёт не так до завершения операции; однако, поскольку она включает полное копирование исходной таблицы, её выполнение может быть дорогим и медленным.

Стратегия Delete+Insert

ClickHouse добавил «облегчённые удаления» (lightweight deletes) как экспериментальную возможность в версии 22.8. Облегчённые удаления значительно быстрее операций ALTER TABLE ... DELETE, поскольку они не требуют перезаписи кусков данных ClickHouse. Инкрементальная стратегия delete+insert использует облегчённые удаления для реализации инкрементальных материализаций, которые работают значительно лучше, чем «устаревшая» (legacy) стратегия. Однако при использовании этой стратегии есть важные ограничения:

  • Облегчённые удаления должны быть включены на вашем сервере ClickHouse с помощью настройки allow_experimental_lightweight_delete=1, либо вы должны задать use_lw_deletes=true в своём профиле (что включит эту настройку для ваших dbt-сессий)
  • Облегчённые удаления теперь считаются готовыми к использованию в продакшене, но на версиях ClickHouse ниже 23.3 могут возникать проблемы с производительностью и другие проблемы.
  • Эта стратегия работает непосредственно с затронутой таблицей/отношением (без создания каких-либо промежуточных или временных таблиц), поэтому, если во время операции возникнет ошибка, данные в инкрементальной модели, скорее всего, окажутся в некорректном состоянии
  • При использовании облегчённых удалений dbt-clickhouse включает настройку allow_nondeterministic_mutations. В некоторых очень редких случаях при использовании недетерминированных incremental_predicates это может привести к состоянию гонки (race condition) для обновлённых/удалённых записей (и соответствующим сообщениям в журналах ClickHouse). Чтобы гарантировать согласованные результаты, инкрементальные предикаты должны включать только подзапросы к данным, которые не будут изменяться во время инкрементальной материализации.
Стратегия Microbatch (требуется dbt-core >= 1.9)

Инкрементальная стратегия microbatch является возможностью dbt-core начиная с версии 1.9, предназначенной для эффективной обработки крупных преобразований временных рядов (time-series data). В dbt-clickhouse она строится поверх существующей инкрементальной стратегии delete_insert, разбивая инкремент на заранее определённые временные батчи на основе конфигураций модели event_time и batch_size.

Помимо обработки крупных преобразований, microbatch позволяет:

Подробную информацию по использованию microbatch см. в официальной документации.

Доступные конфигурации Microbatch
OptionDescriptionDefault if any
event_timeСтолбец, указывающий «в какой момент времени появилась строка». Обязателен для вашей microbatch-модели и любых прямых родительских моделей, которые должны быть отфильтрованы.
begin«Начало временной шкалы» для microbatch-модели. Это стартовая точка для любых первоначальных запусков или запусков с полным обновлением (full-refresh). Например, ежедневная microbatch-модель, запущенная 2024-10-01 с begin = '2023-10-01', обработает 366 батчей (это високосный год!), плюс батч за «сегодня».
batch_sizeГранулярность ваших батчей. Поддерживаемые значения: hour, day, month и year
lookbackОбработка X батчей до последней контрольной точки (bookmark), чтобы захватить поздно прибывшие записи.1
concurrent_batchesПереопределяет автоопределение параллельного выполнения батчей в dbt (одновременно). Подробнее о настройке параллельных батчей. Значение true запускает батчи параллельно. Значение false — последовательно (один за другим).
Стратегия Append

Эта стратегия заменяет настройку inserts_only в предыдущих версиях dbt-clickhouse. Такой подход просто дописывает новые строки в существующее отношение. В результате дубликаты строк не устраняются, и временные или промежуточные таблицы не создаются. Это самый быстрый подход, если дубликаты либо допускаются в данных, либо исключаются предложением/фильтром WHERE в инкрементальном запросе.

Стратегия insert_overwrite (экспериментальная)

[IMPORTANT]
В настоящее время стратегия insert_overwrite работает некорректно с распределёнными материализациями.

Выполняет следующие шаги:

  1. Создайте промежуточную (временную) таблицу с той же структурой, что и инкрементальная модель: CREATE TABLE <staging> AS <target>.
  2. Вставьте в промежуточную таблицу только новые записи (полученные с помощью SELECT).
  3. Замените в целевой таблице только новые партиции (присутствующие в промежуточной таблице).

Этот подход имеет следующие преимущества:

  • Он быстрее стратегии по умолчанию, потому что не копирует всю таблицу.
  • Он безопаснее других стратегий, потому что не изменяет исходную таблицу до тех пор, пока операция INSERT не завершится успешно: в случае промежуточной ошибки исходная таблица не изменяется.
  • Он реализует лучшую практику в data engineering — «неизменяемость партиций», что упрощает инкрементальную и параллельную обработку данных, откаты и т. д.

Для этой стратегии требуется, чтобы partition_by был задан в конфигурации модели. Все остальные параметры конфигурации модели, относящиеся к стратегиям, игнорируются.

Materialization: materialized_view (экспериментально)

Материализация materialized_view должна представлять собой запрос SELECT из существующей (исходной) таблицы. Адаптер создаст целевую таблицу с именем модели и MATERIALIZED VIEW в ClickHouse с именем <model_name>_mv. В отличие от PostgreSQL, материализованное представление ClickHouse не является «статическим» (и не имеет соответствующей операции REFRESH). Вместо этого оно действует как «insert trigger» и будет вставлять новые строки в целевую таблицу, используя определённое в определении представления SELECT- «преобразование» для строк, вставляемых в исходную таблицу. См. тестовый файл для вводного примера того, как использовать эту функциональность.

ClickHouse предоставляет возможность нескольким материализованным представлениям записывать данные в одну и ту же целевую таблицу. Чтобы поддержать это в dbt-clickhouse, вы можете построить UNION в файле модели таким образом, чтобы SQL для каждого из ваших materialized views был обёрнут в комментарии вида --my_mv_name:begin и --my_mv_name:end.

Например, следующий пример создаст два материализованных представления, оба записывающих данные в одну и ту же целевую таблицу модели. Имена материализованных представлений будут иметь вид <model_name>_mv1 и <model_name>_mv2:

--mv1:begin
select a,b,c from {{ source('raw', 'table_1') }}
--mv1:end
union all
--mv2:begin
select a,b,c from {{ source('raw', 'table_2') }}
--mv2:end

ВАЖНО!

При обновлении модели с несколькими материализованными представлениями (MV), особенно при переименовании одного из них, dbt-clickhouse не удаляет старое MV автоматически. Вместо этого вы получите следующее предупреждение: Warning - Table <previous table name> was detected with the same pattern as model name <your model name> but was not found in this run. In case it is a renamed mv that was previously part of this model, drop it manually (!!!)

Догрузка данных

В настоящее время при создании материализованного представления (MV) целевая таблица сначала заполняется историческими данными, и только затем создается само MV.

Другими словами, dbt-clickhouse сначала создает целевую таблицу и загружает в нее исторические данные на основе запроса, определенного для MV. Лишь после этого шага создается MV.

Если вы не хотите выполнять предварительную загрузку исторических данных при создании MV, вы можете отключить это поведение, установив параметр catch-up в значение False:

{{config(
    materialized='materialized_view',
    engine='MergeTree()',
    order_by='(id)',
    catchup=False
)}}

Обновляемые материализованные представления

Чтобы использовать Refreshable Materialized View, при необходимости скорректируйте следующие параметры в вашей MV‑модели (все эти параметры должны быть заданы внутри объекта конфигурации refreshable):

OptionDescriptionRequiredDefault Value
refresh_intervalПараметр интервала (обязательный)Да
randomizeКлауза рандомизации, будет добавлена после RANDOMIZE FOR
appendЕсли установлено в True, при каждом обновлении строки вставляются в таблицу без удаления существующих строк. Вставка не является атомарной, как и обычный запрос INSERT SELECT.False
depends_onСписок зависимостей для обновляемого материализованного представления. Укажите зависимости в следующем формате {schema}.{view_name}
depends_on_validationОпределяет, следует ли проверять наличие зависимостей, указанных в depends_on. Если зависимость указана без схемы, проверка выполняется в схеме defaultFalse

Пример конфигурации для обновляемого материализованного представления:

{{
    config(
        materialized='materialized_view',
        refreshable={
            "interval": "EVERY 5 MINUTE",
            "randomize": "1 MINUTE",
            "append": True,
            "depends_on": ['schema.depend_on_model'],
            "depends_on_validation": True
        }
    )
}}

Ограничения

  • При создании обновляемого материализованного представления (MV) в ClickHouse, которое имеет зависимость, ClickHouse не выдаёт ошибку, если указанная зависимость не существует на момент создания. Вместо этого обновляемое MV остаётся в неактивном состоянии, ожидая выполнения зависимости, прежде чем оно начнёт обрабатывать обновления или выполнять обновление данных. Такое поведение является ожидаемым, но может приводить к задержкам в доступности данных, если требуемая зависимость не будет своевременно обеспечена. Пользователям рекомендуется убедиться, что все зависимости корректно определены и существуют до создания обновляемого материализованного представления.
  • На сегодняшний день не существует фактической «dbt linkage» между mv и его зависимостями, поэтому порядок создания не гарантируется.
  • Функциональность обновляемости не тестировалась с несколькими mv, направляющими данные в одну и ту же целевую модель.

Материализация: dictionary (экспериментальная)

См. тесты в https://github.com/ClickHouse/dbt-clickhouse/blob/main/tests/integration/adapter/dictionary/test_dictionary.py для примеров того, как реализовывать материализации для словарей ClickHouse.

Материализация: distributed_table (экспериментальная)

Распределённая таблица создаётся следующими шагами:

  1. Создаётся временное представление с SQL‑запросом, чтобы получить правильную структуру.
  2. Создаются пустые локальные таблицы на основе представления.
  3. Создаётся распределённая таблица на основе локальных таблиц.
  4. Данные вставляются в распределённую таблицу, поэтому они распределяются по шардам без дублирования.

Примечания:

  • Запросы dbt-clickhouse теперь автоматически включают настройку insert_distributed_sync = 1, чтобы гарантировать корректное выполнение последующих операций инкрементальной материализации. Это может привести к тому, что некоторые вставки в распределённые таблицы будут выполняться медленнее, чем ожидается.

Пример модели распределённой таблицы

{{
    config(
        materialized='distributed_table',
        order_by='id, created_at',
        sharding_key='cityHash64(id)',
        engine='ReplacingMergeTree'
    )
}}

select id, created_at, item
from {{ source('db', 'table') }}

Сгенерированные миграции

CREATE TABLE db.table_local on cluster cluster (
    `id` UInt64,
    `created_at` DateTime,
    `item` String
)
    ENGINE = ReplacingMergeTree
    ORDER BY (id, created_at)
    SETTINGS index_granularity = 8192;

CREATE TABLE db.table on cluster cluster (
    `id` UInt64,
    `created_at` DateTime,
    `item` String
)
    ENGINE = Distributed ('cluster', 'db', 'table_local', cityHash64(id));

materialization: distributed_incremental (экспериментальная)

Инкрементальная модель, основанная на той же идее, что и распределённая таблица; основная сложность — корректно обрабатывать все стратегии инкрементального обновления.

  1. Стратегия Append просто вставляет данные в распределённую таблицу.
  2. Стратегия Delete+Insert создаёт распределённую временную таблицу для работы со всеми данными на каждом шарде.
  3. Стратегия Default (Legacy) создаёт распределённые временные и промежуточные таблицы по той же причине.

Заменяются только таблицы шардов, потому что распределённая таблица не хранит данные. Распределённая таблица пересоздаётся только при включённом режиме full_refresh или если структура таблицы могла измениться.

Пример распределённой инкрементальной модели

{{
    config(
        materialized='distributed_incremental',
        engine='MergeTree',
        incremental_strategy='append',
        unique_key='id,created_at'
    )
}}

select id, created_at, item
from {{ source('db', 'table') }}

Сгенерированные миграции

CREATE TABLE db.table_local on cluster cluster (
    `id` UInt64,
    `created_at` DateTime,
    `item` String
)
    ENGINE = MergeTree
    SETTINGS index_granularity = 8192;

CREATE TABLE db.table on cluster cluster (
    `id` UInt64,
    `created_at` DateTime,
    `item` String
)
    ENGINE = Distributed ('cluster', 'db', 'table_local', cityHash64(id));

Snapshot

Снимки dbt позволяют фиксировать изменения изменяемой модели со временем. В свою очередь, это позволяет выполнять запросы к моделям в разрезе конкретного момента времени, когда аналитики могут «заглянуть в прошлое» и увидеть предыдущее состояние модели. Эта функциональность поддерживается коннектором ClickHouse и настраивается с помощью следующего синтаксиса:

Блок конфигурации в snapshots/<model_name>.sql:

{{
   config(
     schema = "<имя-схемы>",
     unique_key = "<имя-столбца>",
     strategy = "<стратегия>",
     updated_at = "<имя-столбца-updated-at>",
   )
}}

Для получения дополнительной информации о конфигурации см. справочную страницу snapshot configs.

Контракты и ограничения

Поддерживаются только контракты с точным совпадением типов столбцов. Например, контракт с типом столбца UInt32 завершится с ошибкой, если модель вернёт UInt64 или другой целочисленный тип. ClickHouse также поддерживает только ограничения CHECK на уровне всей таблицы/модели. Ограничения первичного ключа, внешнего ключа, уникальности и ограничения CHECK на уровне отдельных столбцов не поддерживаются. (См. документацию ClickHouse по первичным ключам/ключам ORDER BY.)

Дополнительные макросы ClickHouse

Вспомогательные макросы материализации моделей

Следующие макросы включены для упрощения создания специфичных для ClickHouse таблиц и представлений:

  • engine_clause -- использует свойство конфигурации модели engine для назначения движка таблицы ClickHouse. По умолчанию dbt-clickhouse использует движок MergeTree.
  • partition_cols -- использует свойство конфигурации модели partition_by для назначения ключа партиционирования в ClickHouse. По умолчанию ключ партиционирования не назначается.
  • order_cols -- использует конфигурацию модели order_by для назначения ключа сортировки/ORDER BY в ClickHouse. Если не указано, ClickHouse будет использовать пустой кортеж () и таблица будет неотсортированной.
  • primary_key_clause -- использует свойство конфигурации модели primary_key для назначения первичного ключа ClickHouse. По умолчанию первичный ключ установлен, и ClickHouse будет использовать выражение ORDER BY в качестве первичного ключа.
  • on_cluster_clause -- использует свойство профиля cluster для добавления предложения ON CLUSTER к определённым операциям dbt: распределённым материализациям, созданию представлений, созданию баз данных.
  • ttl_config -- использует свойство конфигурации модели ttl для назначения выражения TTL таблицы ClickHouse. По умолчанию TTL не назначен.

Вспомогательный макрос s3Source

Макрос s3source упрощает процесс выборки данных ClickHouse непосредственно из S3 с помощью табличной функции ClickHouse S3. Он работает за счёт заполнения параметров табличной функции S3 из именованного словаря конфигурации (имя словаря должно заканчиваться на s3). Макрос сначала ищет словарь в vars профиля, а затем в конфигурации модели. Словарь может содержать любой из следующих ключей, используемых для заполнения параметров табличной функции S3:

Argument NameDescription
bucketБазовый URL бакета, например https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi. Если протокол не указан, предполагается https://.
pathПуть в S3, используемый для запроса к таблице, например /trips_4.gz. Поддерживаются шаблоны (wildcards) S3.
fmtОжидаемый формат входных данных ClickHouse (например, TSV или CSVWithNames) для указанных объектов S3.
structureСтруктура столбцов данных в бакете в виде списка пар имя/тип, например ['id UInt32', 'date DateTime', 'value String']. Если не указано, ClickHouse попытается автоматически определить структуру.
aws_access_key_idИдентификатор ключа доступа S3.
aws_secret_access_keyСекретный ключ S3.
role_arnARN роли ClickhouseAccess IAM, используемой для безопасного доступа к объектам S3. Дополнительную информацию см. в этой документации.
compressionМетод сжатия, используемый для объектов S3. Если не указан, ClickHouse попытается определить тип сжатия по имени файла.

См. тестовый файл S3 для примеров использования этого макроса.

Поддержка межбазовых макросов

dbt-clickhouse поддерживает большинство межбазовых макросов, теперь включённых в dbt Core, за следующими исключениями:

  • SQL-функция split_part реализована в ClickHouse с использованием функции splitByChar. Эта функция требует использования константной строки в качестве разделителя, поэтому параметр delimeter, используемый для этого макроса, будет интерпретироваться как строка, а не как имя столбца.
  • Аналогично, SQL-функция replace в ClickHouse требует константные строки для параметров old_chars и new_chars, поэтому при вызове этого макроса эти параметры будут интерпретироваться как строки, а не как имена столбцов.