日本語カラム名のテーブルに dbt Semantic Layer のセマンティックモデルを定義する

日本語カラム名のテーブルに dbt Semantic Layer のセマンティックモデルを定義する

2026.04.18

はじめに

カラム名が日本語のテーブルに対して、dbt Semantic Layer(MetricFlow)のセマンティックモデルを定義できるかを検証した際の内容を記事としました。

dbt Semantic Layer における日本語カラム名対応

先に結論を述べると、dbt Semantic Layer では YAML でセマンティックモデルを定義する際、エンティティ名・ディメンション名・メトリクス名といったセマンティック識別子に ASCII 文字しか使用できません。

そのため、DWH 上のテーブルに日本語カラム名が含まれている場合entity: name:dimension: name:を明示的に指定しないと、カラム名がそのままセマンティック識別子として使われてしまい、パースが通りません。

entity: name:dimension: name:に ASCII 名を指定することでセマンティック識別子を上書きでき、この問題を回避できます。

以降で、各設定パターンを確認してみます。

前提条件

検証環境

以下の環境を使用しています。

  • DWH:Snowflake
  • dbt
    • dbt platform(dbt-fusion)

また、この記事では dbt Fusion エンジンおよび dbt platform Latest リリーストラックで利用可能な新しい YAML 記法(モデルのcolumns配下にセマンティックモデル定義を記述する形式)を使用しています。

https://docs.getdbt.com/docs/build/latest-metrics-spec?version=1.12

事前準備

検証用にstg_ordersとして日本語カラム名を含むモデルstg_test_japaneseを作成します。金額は検証用のダミー数値カラムです。

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

select
    order_id                                    as "注文ID",
    customer_id                                 as "顧客ID",
    order_date                                  as "注文日",
    status                                      as "ステータス",
    abs(hash(order_id)) % 9901 + 100            as "金額"

from {{ ref('stg_orders') }}

日本語カラム名テーブルへのセマンティックモデル定義

パターン1:name:に日本語をそのまま記述した場合

はじめに、columns: - name:に日本語をそのまま記述してみます。

version: 2

models:
  - name: stg_test_japanese
    description: 日本語カラム名の検証用モデル
    semantic_model:
      enabled: true
    agg_time_dimension: 注文日

    columns:
      - name: 注文ID
        entity:
          type: primary
          name: japanese_orders

      - name: 注文日
        granularity: day
        dimension:
          type: time

      - name: ステータス
        dimension:
          type: categorical

    metrics:
      - name: 注文数
        type: simple
        agg: count
        expr: 1

dbt parseを実行すると以下のエラーが発生します。

$ dbt parse
14:25:41 error: dbt0102: The metric name '注文数' is invalid. It must begin with a letter
14:25:42 error: dbt1005: Invalid name `注文日` - names may only contain lower case letters, numbers, and underscores. ...
14:25:42 error: dbt1005: Invalid name `ステータス` - names may only contain lower case letters, numbers, and underscores. ...
14:25:42 error: dbt1005: Invalid Semantic Manifest
==================== Execution Summary =====================
Finished 'parse' with 4 errors for target 'dev' [198ms]

columns: - name:の値はそのままセマンティック識別子として検証されるため、日本語は使用できません。

パターン2:ダブルクォートで囲む

次に、YAML のダブルクォートで値を囲んでみます。

    columns:
      - name: "注文ID"
        entity:
          type: primary
          name: japanese_orders

      - name: "注文日"
        granularity: day
        dimension:
          type: time

      - name: "ステータス"
        dimension:
          type: categorical
$ dbt parse
14:27:07 error: dbt1005: Invalid name `注文日` - names may only contain lower case letters, numbers, and underscores. ...
14:27:07 error: dbt1005: Invalid name `ステータス` - names may only contain lower case letters, numbers, and underscores. ...
14:27:07 error: dbt1005: Invalid Semantic Manifest
==================== Execution Summary =====================
Finished 'parse' with 3 errors for target 'dev' [116ms]

YAML のダブルクォートは文字列リテラルの記法であり、値は注文日と同じ(ダブルクォートは消える)です。MetricFlow の識別子制約を回避できません。

パターン3:'"日本語"'形式でname:上書きなし

シングルクォート内にダブルクォートを含める形式('"注文日"')で物理カラム名を参照できます。ただし、この場合はダブルクォートを含む文字列("注文日")がそのままセマンティック識別子として使われます。

    columns:
      - name: '"注文ID"'
        entity:
          type: primary
          name: japanese_orders

      - name: '"注文日"'
        granularity: day
        dimension:
          type: time         # name: の上書きなし

      - name: '"ステータス"'
        dimension:
          type: categorical  # name: の上書きなし
$ dbt parse
error: dbt1005: Invalid name `"注文日"` - names may only contain lower case letters, numbers, and underscores. ...
error: dbt1005: Invalid name `"ステータス"` - names may only contain lower case letters, numbers, and underscores. ...
error: dbt1005: Invalid Semantic Manifest
Finished 'parse' with 3 errors for target 'dev'

ダブルクォート文字(")も識別子として無効のため、エラーとなります。

'"日本語"'形式 + dimension: name: / entity: name:で ASCII 上書き

columns: - name:に先と同じ手順で物理カラム名を指定し、dimension: name: / entity: name:を追加設定します。
これにより、MetricFlow のセマンティック名が上書きされます。セマンティック識別子は ASCII 名となるため、パースに成功します。

version: 2

models:
  - name: stg_test_japanese
    description: 日本語カラム名の検証用モデル
    semantic_model:
      enabled: true
    agg_time_dimension: order_date_ja   # time dimension の name: と一致させる

    columns:
      - name: '"注文ID"'
        description: 注文の一意識別子
        entity:
          type: primary
          name: japanese_orders

      - name: '"注文日"'
        description: 注文が作成された日付
        granularity: day
        dimension:
          type: time
          name: order_date_ja           # agg_time_dimension から参照される ASCII 名

      - name: '"ステータス"'
        description: 注文のステータス
        dimension:
          type: categorical
          name: status                  # MetricFlow のセマンティック名(ASCII 必須)

      - name: '"顧客ID"'
        description: 顧客の識別子

    metrics:
      - name: order_count_ja
        type: simple
        agg: count
        expr: 1
$ dbt parse
14:34:20 Artifact written to target/semantic_manifest.json
14:34:20 Artifact written to target/manifest.json
==================== Execution Summary =====================
Finished 'parse' successfully for target 'dev' [120ms]

パースに成功しました。ディメンションの一覧とクエリも問題なく動作します。

$ dbt sl list dimensions --metrics order_count_ja
The list of available dimensions:
- japanese_orders__order_date_ja
- japanese_orders__status
- metric_time
$ dbt sl query --metrics order_count_ja --group-by japanese_orders__status
+-------------------------+----------------+
| JAPANESE_ORDERS__STATUS | ORDER_COUNT_JA |
+-------------------------+----------------+
| completed               |             67 |
| shipped                 |             13 |
| return_pending          |              2 |
| placed                  |             13 |
| returned                |              4 |
+-------------------------+----------------+

--compileで生成される SQL を確認すると、日本語カラムが引用符付きで正しく参照されていることが分かります。

SELECT
  japanese_orders__status
  , SUM(__order_count_ja) AS order_count_ja
FROM (
  SELECT
    "ステータス" AS japanese_orders__status
    , 1 AS __order_count_ja
  FROM dbt_sl_db.dbt_tyasuhara.stg_test_japanese stg_test_japanese_src_10000
) subq_3
GROUP BY
  japanese_orders__status
LIMIT 100

metrics の expr で日本語カラムを計算する

metrics: expr:は SQL 式として評価されるため、"金額" のような日本語カラム名と計算式をそのまま記述できます。

metrics:
  - name: tax_amount_ja
    type: simple
    agg: sum
    expr: '"金額" * 0.1'             # 日本語カラムへの参照 + 計算式

  - name: total_amount_ja
    type: simple
    agg: sum
    expr: '"金額"'                   # 日本語カラムの直接参照
$ dbt sl query --metrics tax_amount_ja,total_amount_ja --group-by japanese_orders__status
+-------------------------+---------------+-----------------+
| JAPANESE_ORDERS__STATUS | TAX_AMOUNT_JA | TOTAL_AMOUNT_JA |
+-------------------------+---------------+-----------------+
| returned                |        1354.7 |           13547 |
| completed               |       35087.9 |          350879 |
| return_pending          |         546.6 |            5466 |
| shipped                 |        5788.4 |           57884 |
| placed                  |        5821.4 |           58214 |
+-------------------------+---------------+-----------------+

コンパイル SQL:

$ dbt sl query --metrics tax_amount_ja,total_amount_ja --group-by japanese_orders__status --compile
SELECT
  japanese_orders__status
  , SUM(__tax_amount_ja) AS tax_amount_ja
  , SUM(__total_amount_ja) AS total_amount_ja
FROM (
  SELECT
    "ステータス" AS japanese_orders__status
    , "金額" * 0.1 AS __tax_amount_ja
    , "金額" AS __total_amount_ja
  FROM dbt_sl_db.dbt_tyasuhara.stg_test_japanese stg_test_japanese_src_10000
) subq_3
GROUP BY
  japanese_orders__status
LIMIT 100

derived_semantics の expr で複合主キーを定義する

derived_semantics: entities: expr:も SQL 式として評価されるため、"注文ID" のような日本語カラム名をそのまま使えます。

derived_semantics:
  entities:
    - name: japanese_orders          # セマンティック名は ASCII
      type: primary
      expr: "CAST(\"注文ID\" AS VARCHAR) || '-' || CAST(\"顧客ID\" AS VARCHAR)"
$ dbt sl query --metrics order_count_ja --group-by japanese_orders
+-----------------+----------------+
| JAPANESE_ORDERS | ORDER_COUNT_JA |
+-----------------+----------------+
| 2-3             |              1 |
| 17-71           |              1 |
・・・
+-----------------+----------------+

コンパイル SQL:

dbt sl query --metrics order_count_ja --group-by japanese_orders --compile
SELECT
  japanese_orders
  , SUM(__order_count_ja) AS order_count_ja
FROM (
  SELECT
    CAST("注文ID" AS VARCHAR) || '-' || CAST("顧客ID" AS VARCHAR) AS japanese_orders
    , 1 AS __order_count_ja
  FROM dbt_sl_db.dbt_tyasuhara.stg_test_japanese stg_test_japanese_src_10000
) subq_3
GROUP BY
  japanese_orders
LIMIT 100

派生メトリクス

派生メトリクスはメトリクスをそのまま参照するので、特に問題ありません。

- name: avg_tax_per_order_ja
  type: derived
  expr: tax_amount_ja / order_count_ja   # メトリクス名(ASCII)を参照するため日本語制約なし
  input_metrics:
    - name: tax_amount_ja
    - name: order_count_ja

検証内容のまとめ

検証した内容をまとめると以下の通りです。MetricFlow のセマンティック識別子(名前として使われるもの)と SQL 式(値として評価されるもの)で、日本語使用可否の制約が異なります。

YAML のキー 用途 日本語使用
columns: - name: 物理カラムへの参照 + セマンティック識別子のデフォルト名 識別子として検証される
entity: name: / dimension: name: MetricFlow のセマンティック識別子 ASCII のみ(lowercase + underscore)
agg_time_dimension: time dimension の name: を参照 ASCII のみ
metrics: - name: メトリクス識別子 ASCII のみ
metrics: expr: SQL 式 "金額"のように引用符付きで参照可能
derived_semantics: entities: expr: SQL 式(複合キー) "金額"のように引用符付きで参照可能

Label の付与

label:で MetricFlow のセマンティック定義に表示名を付与できます。こちらであればname:(識別子)とは独立して設定でき、日本語も使えます。

metrics:
      - name: order_count_ja
        type: simple
        label: 注文数
        agg: count
        expr: 1

      - name: tax_amount_ja
        type: simple
        label: 消費税額
        agg: sum
        expr: '"金額" * 0.1'

      - name: total_amount_ja
        type: simple
        label: 金額合計
        agg: sum
        expr: '"金額"'

      - name: avg_tax_per_order_ja
        type: derived
        label: 注文あたり消費税額
        expr: tax_amount_ja / order_count_ja
        input_metrics:
          - name: tax_amount_ja
          - name: order_count_ja

下図は Steep の例ですが、対応する BI ツールであれば label で付与した名称でメトリクスやディメンションが表示されます。

2026-04-18_12h39_16

さいごに

カラム名が日本語のテーブルに対して dbt Semantic Layer(MetricFlow)のセマンティックモデルを定義する方法を確認してみました。
こちらの内容がどなたかの参考になれば幸いです。

この記事をシェアする

関連記事