profiles.yml: подключение к хранилищу

Где dbt хранит данные для подключения и почему этот файл лежит вне проекта.

profiles.yml — файл с параметрами подключения к хранилищу (хост, пользователь, база, схема), который dbt ищет в домашней папке пользователя, а не в репозитории проекта.

Зачем отдельный файл вне проекта

Проект dbt лежит в git и общий для всей команды. Но пароли и доступы к хранилищу — личные и секретные. Поэтому dbt намеренно разделяет два файла: dbt_project.yml (логика проекта, в git) и profiles.yml (доступы, обычно в ~/.dbt/, вне git). Так секреты не утекают в репозиторий, а каждый разработчик подключается под своими кредами.

Структура profiles.yml

my_analytics:           # имя профиля = profile в dbt_project.yml
  target: dev           # какая цель используется по умолчанию
  outputs:
    dev:                # цель для разработки
      type: postgres
      host: localhost
      port: 5432
      user: "{{ env_var('DBT_USER') }}"
      password: "{{ env_var('DBT_PASSWORD') }}"
      dbname: analytics
      schema: dbt_dev   # моя личная схема для экспериментов
      threads: 4
    prod:               # цель для продакшена
      type: postgres
      host: warehouse.company.com
      port: 5432
      user: "{{ env_var('DBT_PROD_USER') }}"
      password: "{{ env_var('DBT_PROD_PASSWORD') }}"
      dbname: analytics
      schema: analytics
      threads: 8

Цели (targets): dev и prod в одном файле

Внутри одного профиля можно описать несколько целей (outputs). Поле target выбирает активную по умолчанию. Это позволяет одним и тем же кодом писать в личную схему при разработке и в общую — на продакшене:

# Запуск в dev-схему (по умолчанию)
dbt run

# Запуск в prod-схему
dbt run --target prod

Секреты через переменные окружения

Пароли в открытом виде в файле — плохо даже вне git. Функция env_var подставляет значение из переменной окружения, так что сам файл не содержит секретов:

export DBT_USER=analyst
export DBT_PASSWORD=super_secret
dbt run   # dbt подставит значения из окружения

Как работает под капотом

При запуске dbt сопоставляет поле profile из dbt_project.yml с одноимённым ключом в profiles.yml, берёт активную цель (или ту, что указана в --target), резолвит все env_var и открывает соединение через адаптер. Параметр threads говорит, сколько моделей dbt будет строить параллельно — независимые ветви DAG выполняются одновременно.

Частые ошибки

  • Закоммитить profiles.yml с паролями в git. Файл держат вне репозитория и используют env_var.
  • Несовпадение имени профиля. Ключ в profiles.yml должен точно совпадать с profile из dbt_project.yml, иначе dbt не найдёт подключение.
  • Писать в общую схему при разработке. Для dev задавайте личную схему, чтобы не мешать коллегам и проду.

Итоги

  • profiles.yml хранит доступы к хранилищу и лежит вне git, в ~/.dbt/.
  • Несколько целей (dev/prod) в одном профиле переключаются флагом --target.
  • Секреты подставляются через env_var, а не пишутся в файл.
Проверьте себя
1. Почему profiles.yml хранят вне репозитория проекта?
AТак быстрее работает dbt
BЧтобы секретные доступы к хранилищу не попадали в git
CЭто требование SQL
DЧтобы файл было проще редактировать
2. Что задают цели (targets) dev и prod в одном профиле?
AРазные языки SQL
BРазные подключения/схемы для разработки и продакшена при одном и том же коде
CРазные версии dbt
DРазные модели