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

JDBC API StarterEnterpriseEnterprise +

Java Database Connectivity (JDBC) API для Semantic Layer позволяет пользователям выполнять запросы к метрикам и измерениям с использованием протокола JDBC, а также предоставляет стандартную функциональность работы с метаданными.

JDBC-драйвер — это программный компонент, позволяющий Java-приложению взаимодействовать с платформой данных. Вот дополнительная информация о нашем JDBC API:

  • JDBC API для Semantic Layer использует open-source JDBC‑драйвер с протоколом ArrowFlight SQL.
  • Вы можете скачать JDBC‑драйвер с Maven.
  • Semantic Layer поддерживает ArrowFlight SQL driver версии 12.0.0 и выше.
  • Вы можете встроить драйвер в стек своего приложения по мере необходимости и использовать пример проекта от dbt Labs в качестве ориентира.
  • Если вы партнёр или пользователь, разрабатывающий собственное (homegrown) приложение, вам потребуется установить корневой сертификат AWS (AWS root CA) в Java Trust. Подробности см. в документации (актуально для Java и JDBC‑вызовов).

Партнёры dbt Labs могут использовать JDBC API для создания интеграций своих инструментов с Semantic Layer.

Использование JDBC API

Если вы пользователь или партнёр dbt и у вас есть доступ к dbt и Semantic Layer, вы можете настроить и протестировать этот API на данных из вашего собственного инстанса, сконфигурировав Semantic Layer и получив корректные параметры JDBC‑подключения, описанные в этом документе.

Вы можете использовать наш JDBC API и с инструментами, у которых нет официальной интеграции с Semantic Layer. Если используемый вами инструмент позволяет писать SQL и либо поддерживает универсальный JDBC‑драйвер (например, DataGrip), либо поддерживает Dremio и использует драйвер ArrowFlightSQL версии 12.0.0 или выше, вы сможете получить доступ к API Semantic Layer.

Дополнительную информацию см. в разделе Get started with the Semantic Layer.

Обратите внимание, что GraphQL API Semantic Layer не поддерживает использование ref для обращения к объектам dbt. Вместо этого необходимо использовать полностью квалифицированное имя таблицы. Если вы используете макросы dbt во время выполнения запроса для расчёта метрик, такие вычисления следует перенести в определения метрик Semantic Layer в виде кода.

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

dbt авторизует запросы к API Semantic Layer. Вам необходимо указать Environment ID, Host и service account tokens или personal access tokens.

Параметры подключения

Подключение JDBC требует нескольких различных параметров подключения.

Вот пример строки подключения URL и отдельных компонентов:

jdbc:arrow-flight-sql://semantic-layer.cloud.getdbt.com:443?&environmentId=202339&token=AUTHENTICATION_TOKEN
Параметр JDBCОписаниеПример
jdbc:arrow-flight-sql://Протокол для JDBC-драйвера.jdbc:arrow-flight-sql://
semantic-layer.cloud.getdbt.comURL доступа для региона вашего аккаунта в dbt. Перед URL доступа всегда необходимо добавлять префикс semantic-layer.Для развертывания dbt в Северной Америке используйте semantic-layer.cloud.getdbt.com
environmentIdУникальный идентификатор продакшн‑окружения dbt. Его можно получить из URL dbt, когда вы переходите в раздел Environments в меню Deploy.Если ваш URL оканчивается на .../environments/222222, то значение environmentId222222

AUTHENTICATION_TOKENВы можете использовать либо service token dbt с правами “Semantic Layer Only” и “Metadata Only”, либо personal access token dbt. Новый service token или personal token создаётся на странице Account Settings.token=AUTHENTICATION_TOKEN
Loading table...

*Примечание — Если вы тестируете локально на инструменте, таком как DataGrip, вам также может потребоваться предоставить следующую переменную в конце или начале URL JDBC &disableCertificateVerification=true.

Запрос метаданных через API

JDBC API Semantic Layer имеет встроенные вызовы для работы с метаданными, которые позволяют пользователю получать информацию о своих метриках и измерениях.

Разверните следующие переключатели для примеров и команд метаданных:

 Получить определенные метрики

Вы можете использовать этот запрос для получения всех определенных метрик в вашем проекте dbt:

select * from {{ 
semantic_layer.metrics()
}}
 Получить измерения для метрики

Вы можете использовать этот запрос для получения всех измерений для метрики.

Обратите внимание, что метрики — это обязательный аргумент, который перечисляет одну или несколько метрик.

select * from {{ 
semantic_layer.dimensions(metrics=['food_order_amount'])}}
 Получение гранулярностей для метрик

Вы можете использовать этот запрос для получения доступных гранулярностей для списка метрик.

Этот запрос API позволяет вам показывать только те временные гранулярности, которые имеют смысл для основной временной размерности метрик (например, metric_time), но если вы хотите получить доступные гранулярности для других временных размерностей, вы можете использовать вызов dimensions() и найти столбец queryable_granularities.

Обратите внимание, что метрики — это обязательный аргумент, который перечисляет одну или несколько метрик.

select * from {{
semantic_layer.queryable_granularities(metrics=['food_order_amount', 'order_gross_profit'])}}
 Получить доступные метрики для заданных измерений

Вы можете использовать этот запрос для получения доступных метрик для заданных измерений. Эта команда по сути является противоположностью получения измерений для списка метрик.

Обратите внимание, что group_by — это обязательный аргумент, который перечисляет одно или несколько измерений.

select * from {{
semantic_layer.metrics_for_dimensions(group_by=['customer__customer_type'])
}}
 Получить гранулярности для всех временных измерений

Вы можете использовать этот пример запроса для получения доступных гранулярностей для всех временных измерений (аналогичный вызов API queryable granularities возвращает только гранулярности для основных временных измерений для метрик).

Следующий вызов является производным от вызова dimensions() и специально выбирает поле гранулярности.

select NAME, QUERYABLE_GRANULARITIES from {{
semantic_layer.dimensions(
metrics=["order_total"]
)
}}
 Получить имена основных временных измерений

В вашем приложении может быть полезно отображать имена временных измерений, которые представляют metric_time или общую нить для всех метрик.

Сначала вы можете выполнить запрос аргумента metrics() для получения списка мер, затем использовать вызов measures(), который вернет имя(а) временных измерений, составляющих metric_time.

select * from {{
semantic_layer.measures(metrics=['orders'])
}}
 Получить метрики по поиску подстроки

Вы можете отфильтровать ваши метрики, чтобы включить только те, которые содержат определенную подстроку (последовательность символов, содержащаяся в более длинной строке (тексте)). Используйте аргумент search, чтобы указать подстроку, которую вы хотите сопоставить.

select * from {{ semantic_layer.metrics(search='order') }}

Если подстрока не указана, запрос возвращает все метрики.

 Пагинация вызовов метаданных

В случае, если вы не хотите возвращать полный набор результатов из вызова метаданных, вы можете разбить результаты на страницы как для вызовов semantic_layer.metrics(), так и для semantic_layer.dimensions() с использованием параметров page_size и page_number.

  • page_size: Это необязательная переменная, которая устанавливает количество записей на странице. Если оставить None, ограничения на количество страниц нет.
  • page_number: Это необязательная переменная, которая указывает номер страницы для получения. По умолчанию 1 (первая страница), если не указано.

Примеры:

-- Получает 5-ю страницу с размером страницы 10 метрик
select * from {{ semantic_layer.metrics(page_size=10, page_number=5) }}

-- Получает 1-ю страницу с размером страницы 10 метрик
select * from {{ semantic_layer.metrics(page_size=10) }}

-- Получает все метрики без пагинации
select * from {{ semantic_layer.metrics() }}

Вы можете использовать те же параметры пагинации для semantic_layer.dimensions(...).

 Список сохраненных запросов

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

Команда

select * from semantic_layer.saved_queries()

Вывод

| NAME | DESCRIPTION | LABEL | METRICS | GROUP_BY | WHERE_FILTER |
 Fetch metric aliases

Вы можете запрашивать метрики, используя алиасы — более простые или интуитивно понятные имена — даже если алиас не определён в конфигурации метрики. Запрос вернёт алиас в качестве имени метрики, например:

select * from {{
semantic_layer.query(metrics=[Metric("metric_name", alias="metric_alias")])
}}

В этом примере, если вы зададите алиас banana для метрики revenue, запрос вернёт колонку с именем banana, даже если banana не определён в конфигурации метрики. Однако при использовании Jinja‑условий where необходимо ссылаться на фактическое имя метрики (revenue в данном случае), а не на алиас.

Более подробный пример см. в разделе Query metric alias.

Запрос значений через API

Для запроса значений доступны следующие параметры. Ваш запрос должен содержать либо параметр metric, либо параметр group_by, чтобы считаться валидным.

| Parameter |

Description
|
Example
| | | --------- | -----------| ------------ | | metrics | Имя метрики, как определено в вашей конфигурации метрик dbt | metrics=['revenue'] | | group_by | Имена измерений или сущностей для группировки. Мы требуем ссылки на сущность измерения (кроме основной временной размерности), которая добавляется перед именем измерения с двойным подчеркиванием. | group_by=['user__country', 'metric_time'] | | grain | Параметр, специфичный для любой временной размерности, изменяющий гранулярность данных по умолчанию для метрики. | group_by=[Dimension('metric_time')
grain('week\|day\|month\|quarter\|year')] | | where | Условие where, позволяющее фильтровать по измерениям и сущностям с использованием параметров. Это принимает список фильтров ИЛИ строку. Входные данные поставляются с объектами Dimension и Entity. Гранулярность требуется, если Dimension является временной размерностью | "{{ where=Dimension('customer__country') }} = 'US')" | | limit | Ограничение на возвращаемые данные | limit=10 | |order | Упорядочивание возвращаемых данных по определенному полю | order_by=['order_gross_profit'], используйте - для убывания, или полную нотацию объекта, если объект подвергается операции: order_by=[Metric('order_gross_profit').descending(True)] | | compile | Если true, возвращает сгенерированный SQL для платформы данных, но не выполняет его | compile=True | | saved_query | Сохраненный запрос, который вы можете использовать для часто используемых запросов. | select * from {{ semantic_layer.query(saved_query="new_customer_orders" |

Примечание о временных измерениях и metric_time

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

Вы можете рассматривать одну метрику или сотни метрик, и если вы группируете по metric_time, это всегда даст вам правильный временной ряд.

Кроме того, при выполнении расчетов гранулярности, которые являются глобальными (не специфичными для конкретного временного измерения), мы рекомендуем всегда работать с metric_time, и вы получите правильный ответ.

Обратите внимание, что metric_time должен быть доступен в дополнение к любым другим временным измерениям, доступным для метрики(ов). В случае, если вы рассматриваете одну метрику (или несколько метрик из одного источника данных), значения в серии для основной временной размерности и metric_time эквивалентны.

Примеры

В следующих разделах приведены примеры того, как выполнять запросы к метрикам с использованием JDBC API:

  • Fetch metadata for metrics — Фильтрация или добавление любого SQL-кода вне шаблонного синтаксиса.
  • Query common dimensions — Выбор общих измерений для нескольких метрик.
  • Query grouped by time — Получение данных о выручке и новых клиентах с группировкой по времени.
  • Query with a time grain — Получение нескольких метрик с изменением гранулярности временного измерения.
  • Group by categorical dimension — Группировка по категориальному измерению.
  • Query only a dimension — Получение полного списка значений для выбранного измерения.
  • Query by all dimensions — Выполнение запроса с использованием всех допустимых измерений.
  • Query with where filters — Использование параметра where для фильтрации по измерениям и сущностям с помощью параметров.
  • Query with a limit — Выполнение запроса с использованием limit или order_by.
  • Query with order by examples — Запрос с использованием order_by, который принимает простую строку, представляющую Dimension, Metric или Entity. По умолчанию используется сортировка по возрастанию. Для сортировки по убыванию добавьте символ - перед объектом.
  • Query with compile keyword — Выполнение запроса с использованием ключевого слова compile для предварительного просмотра итогового SQL перед выполнением.
  • Query a saved query — Выполнение запроса с использованием сохранённого запроса с дополнительными параметрами, такими как limit или where.
  • Query metric alias — Запрос метрик с использованием алиасов, которые позволяют применять более простые или интуитивно понятные имена вместо полных определений метрик.
  • Multi-hop joins — Выполнение запросов через несколько связанных таблиц (multi-hop joins) с использованием аргумента entity_path для указания пути между связанными сущностями.

Вы можете фильтровать/добавлять любой SQL вне синтаксиса шаблонизации. Например, вы можете использовать следующий запрос для получения имени и измерений для метрики:

select name, dimensions from {{ 
semantic_layer.metrics()
}}
WHERE name='food_order_amount'

Запрос общих измерений

Вы можете выбрать общие измерения для нескольких метрик. Используйте следующий запрос для получения имени и измерений для нескольких метрик:

select * from {{ 
semantic_layer.dimensions(metrics=['food_order_amount', 'order_gross_profit'])
}}

Запрос с группировкой по времени

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

select * from {{
semantic_layer.query(metrics=['food_order_amount','order_gross_profit'],
group_by=['metric_time'])
}}

Запрос с временной гранулярностью

Используйте следующий пример запроса для получения нескольких метрик с изменением гранулярности временной размерности:

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('month')])
}}

Группировка по категориальному измерению

Используйте следующий запрос для группировки по категориальному измерению:

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('month'), 'customer__customer_type'])
}}

Запрос только измерения

В этом случае вы получите полный список значений измерений для выбранного измерения.

select * from {{
semantic_layer.query(group_by=['customer__customer_type'])
}}

Запрос по всем измерениям

Вы можете использовать endpoint semantic_layer.query_with_all_group_bys, чтобы выполнить запрос по всем допустимым измерениям.

select * from {{
semantic_layer.query_with_all_group_bys(metrics =['revenue','orders','food_orders'],
compile= True)
}}

В результате будут возвращены все измерения, которые являются допустимыми для набора метрик, указанных в запросе.

Запрос с фильтрами where

Фильтры where в API позволяют использовать список фильтров или строку. Мы рекомендуем использовать список фильтров для производственных приложений, так как этот формат реализует все преимущества Predicate pushdown там, где это возможно.

Фильтры Where имеют несколько объектов, которые вы можете использовать:

  • Dimension() — Используется для любых категориальных или временных измерений. Dimension('metric_time').grain('week') или Dimension('customer__country').

  • TimeDimension() — Используется как более явное определение для временных измерений, опционально принимает гранулярность TimeDimension('metric_time', 'month').

  • Entity() — Используется для сущностей, таких как первичные и внешние ключи - Entity('order_id').

Для TimeDimension() гранулярность требуется в фильтре WHERE только в том случае, если временные измерения агрегации для мер и метрик, связанных с фильтром where, имеют разные гранулярности.

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

semantic_model:
name: my_model_source

defaults:
agg_time_dimension: created_month
measures:
- name: measure_0
agg: sum
- name: measure_1
agg: sum
agg_time_dimension: order_year
dimensions:
- name: created_month
type: time
type_params:
time_granularity: month
- name: order_year
type: time
type_params:
time_granularity: year

metrics:
- name: metric_0
description: Метрика с месячной гранулярностью.
type: simple
type_params:
measure: measure_0
- name: metric_1
description: Метрика с годовой гранулярностью.
type: simple
type_params:
measure: measure_1

Предположим, пользователь запрашивает metric_0 и metric_1 вместе в одном запросе, допустимый фильтр WHERE будет:

  • "{{ TimeDimension('metric_time', 'year') }} > '2020-01-01'"

Недопустимые фильтры будут:

  • "{{ TimeDimension('metric_time') }} > '2020-01-01'" — метрики в запросе определены на основе мер с разными гранулярностями.

  • "{{ TimeDimension('metric_time', 'month') }} > '2020-01-01'"metric_1 недоступна на месячной гранулярности.

  • Используйте следующий пример для запроса с использованием фильтра where в строковом формате:
select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('month'),'customer__customer_type'],
where="{{ Dimension('metric_time').grain('month') }} >= '2017-03-09' AND {{ Dimension('customer__customer_type' }} in ('new') AND {{ Entity('order_id') }} = 10")
}}
  • (Рекомендуется для лучшей производительности) Используйте следующий пример для запроса с использованием фильтра where в формате списка фильтров:
select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('month'),'customer__customer_type'],
where=["{{ Dimension('metric_time').grain('month') }} >= '2017-03-09'", "{{ Dimension('customer__customer_type') }} in ('new')", "{{ Entity('order_id') }} = 10"])
}}

Запрос с ограничением

Используйте следующий пример для запроса с использованием limit или order_by:

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time')],
limit=10)
}}

Примеры запросов с order by

Order By может принимать простую строку, которая является Dimension, Metric или Entity, и по умолчанию будет использовать порядок по возрастанию

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time')],
limit=10,
order_by=['order_gross_profit'])
}}

Для убывающего порядка вы можете добавить знак - перед объектом. Однако вы можете использовать эту сокращенную нотацию только в том случае, если вы не выполняете операции над объектом или используете полную нотацию объекта.

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time')],
limit=10,
order_by=['-order_gross_profit'])
}}

Если вы упорядочиваете по объекту, который подвергся операции (например, вы изменили гранулярность временной размерности), или вы используете полную нотацию объекта, убывающий порядок должен выглядеть так:

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('week')],
limit=10,
order_by=[Metric('order_gross_profit').descending(True), Dimension('metric_time').grain('week').descending(True) ])
}}

Аналогично, это приведет к порядку по возрастанию:

select * from {{
semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
group_by=[Dimension('metric_time').grain('week')],
limit=10,
order_by=[Metric('order_gross_profit'), Dimension('metric_time').grain('week')])
}}

Запрос с ключевым словом compile

  • Используйте следующий пример для запроса с использованием ключевого слова compile:

    select * from {{
    semantic_layer.query(metrics=['food_order_amount', 'order_gross_profit'],
    group_by=[Dimension('metric_time').grain('month'),'customer__customer_type'],
    compile=True)
    }}
  • Используйте следующий пример для компиляции SQL с сохраненным запросом. Вы можете использовать это для часто используемых запросов.

    select * from {{ semantic_layer.query(saved_query="new_customer_orders", limit=5, compile=True}}
Примечание о запросе сохраненных запросов

При запросе сохраненных запросов вы можете использовать такие параметры, как where, limit, order, compile и так далее. Однако имейте в виду, что вы не можете получить доступ к параметрам metric или group_by в этом контексте. Это связано с тем, что они являются предопределенными и фиксированными параметрами для сохраненных запросов, и вы не можете изменить их во время выполнения запроса. Если вы хотите запросить больше метрик или измерений, вы можете построить запрос, используя стандартный формат.

Запрос сохраненного запроса

Используйте следующий пример для запроса сохраненного запроса:

select * from {{ semantic_layer.query(saved_query="new_customer_orders", limit=5}}

JDBC API будет использовать сохраненный запрос (new_customer_orders) как определено и применит ограничение в 5 записей.

Алиасы метрик в запросах

Вы можете запрашивать метрики, используя алиасы. Алиасы позволяют использовать более простые или более интуитивно понятные имена для метрик вместо их полных определений.

select * from {{
semantic_layer.query(metrics=[Metric("revenue", alias="metric_alias")])
}}

Например, предположим, что в конфигурации метрик для метрики order_total задан алиас total_revenue_global. В этом случае вы можете запрашивать метрику, используя алиас вместо исходного имени:

select * from {{
semantic_layer.query(metrics=[Metric("order_total", alias="total_revenue_global")], group_by=['metric_time'])
}}

Результат будет следующим:

| METRIC_TIME   | TOTAL_REVENUE_GLOBAL |
|:-------------:|:------------------: |
| 2023-12-01 | 1500.75 |
| 2023-12-02 | 1725.50 |
| 2023-12-03 | 1850.00 |
подсказка

Обратите внимание, что при использовании Jinja-условий where необходимо указывать фактическое имя метрики. Например, если вы использовали banana в качестве алиаса для revenue, то в условии where нужно использовать реальное имя метрики — revenue, а не banana.

semantic_layer.query(metrics=[Metric("revenue", alias="banana")], where="{{ Metric('revenue') }} > 0")

Многошаговые (multi-hop) соединения

В случаях, когда вам нужно выполнить запрос через несколько связанных таблиц (многозвенные соединения), используйте аргумент entity_path, чтобы указать путь между связанными сущностями. Вот примеры того, как вы можете определить эти соединения:

  • В этом примере вы запрашиваете измерение location_name, но указываете, что оно должно быть соединено с использованием поля order_id.
    {{Dimension('location__location_name', entity_path=['order_id'])}}
  • В этом примере измерение salesforce_account_owner соединено с полем region, с путем, проходящим через salesforce_account.
    {{ Dimension('salesforce_account_owner__region',['salesforce_account']) }}

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

Я получаю ошибку `Failed ALPN` при попытке подключения к dbt Semantic Layer
 Почему некоторые измерения используют разный синтаксис, например, `metric_time` против `Dimension('metric_time')`?
 Что означает синтаксис двойного подчеркивания `'__'` в измерениях?
 Каков формат вывода по умолчанию при добавлении гранулярности?

Нашли ошибку?

0
Loading