
Omniでdbtの開発環境のデータを参照しながらSemantic Layerの定義変更・ダッシュボード修正が行える「Dynamic Schema」を試してみた
さがらです。
Omniはdbtと親和性の高い機能をいくつも提供していますが、その中でも特筆すべきなのがdbtの開発環境のデータに対して動的に参照先を切り替えることができるDynamic Schemaの機能です。
この機能を試してみたので、本記事で内容をまとめてみます。
事前準備
前提条件
まず、前提条件として以下を実施済とします。
- SnowflakeへのConnectionを作成済
- Connectionの中で、dbtとの連携設定も完了


- Connectionに対してModelを1つ作成し、そのModelはGitHubとの連携も終えて、Shared Modelの変更にはプルリクエストを必須としている状態(参考:公式Doc)

dbtの開発環境に該当するEnvironmentを新規設定
次に、dbtの開発環境に該当するEnvironmentを新規設定します。
対象のConnectionのdbtタブから、最下部のEnvironmentsでAdd Environmentを押します。


実際のEnvironmentの設定は、下図のように設定します。ポイントは、Default Schemaは開発環境として利用しているスキーマ名、Target Nameはdbtの開発環境として使っているtarget名にすることです。

入力後Saveを押し、下図のようにdbtの開発環境として利用しているスキーマの一覧が表示されます。問題なければこのまま右上の「✕」を押して閉じて問題ありません。

Virtual Schemaの有効化
次に、対象のConnectionのdbtタブから、Enable Virtual Schemasを有効化してSaveを押します。この設定を有効化したことで、omni_dbtという仮想スキーマが作られ、各viewを参照する際はomni_dbt__<view名>の形で参照できるようになり、Dynamic Schema機能で接続先のdbtの環境を切り替えた際にもこの仮想スキーマが吸収して本番環境・開発環境を問わず動的に参照先のスキーマを切り替える事が可能となります。

Virtual Schemaを有効化すると、同じ画面の右側にMigrationという枠が追加表示されるはずです。これは、Virtual Schema有効化前の既存のOmniのSemantic Layerのコードはある環境のスキーマを固定で参照するようになっているため、このMigrationを行うことでomni_dbtスキーマを参照するコードを自動で追加してくれます。
実際に移行をするため、Run migrationを押します。

下図のように表示されるため、左下のOverwriteにチェックを入れて、Run migrationを押します。

この後で実際にShared Modelのコードを見ると、VIRTUAL SCHEMASの欄が追加され、各viewファイルのコードの内容もomni_dbtスキーマを参照するように変更されています。
(作られたVIRTUAL SCHEMASの名称を見ると、omni_dbt_<dbtの本番環境のカスタムスキーマ名>で作られていると感じました。)

既存のコンテンツの参照先をVirtual Schemaのviewに変更
すでにある程度Omniで開発を行っている場合、既存のコンテンツの参照先をOmniのVirtual Schemaのviewに変更する必要があります。
新しいブランチを切って、以下の作業を行います。一通りの作業を終えたら、プルリクエストを発行してマージしましょう。

topicsの参照先のviewの変更
※参考までに、Ctrl + Fを押すと各ファイル内でテキストの検索・置換ができます。
- Before

- After

Workbookの各Queryの参照先のviewの変更
※これは、Workbookの各Queryがtopicsではなく生のviewを参照している場合に必要な作業です。
Content Validatorの画面でShow all documentsを押します。

Replaceを押して、Viewタブを開いていることを確認した上で、下図のように生のテーブルview名からVirtual Schemaのview名に置換するように設定して、Replaceを押します。


この後、ブランチに入っている状態でview名の置換を行ったWorkbookの各Queryを確認し、問題なくグラフ表示がされていることと、いずれかのフィールドでGo to definitionを押してVirtual Schema内のviewの定義にリンクすることを確認できればOKです。


dbtの開発環境を参照するDynamic Schema機能を用いた開発をやってみた
これで準備が整ったので、dbtの開発環境を参照するDynamic Schema機能を用いた開発がどのように行えるか、試していきます!
やること
Omniでも使用しているdbtのModelの中でordered_atというカラムがあるのですが、これをpurchased_atに変更するということを行ってみます。

dbtでブランチを切って開発
dbtでブランチを切って、以下の変更を行います。


この上でdbt CloudのIDE上でdbt buildを行うと、カラム名を変更したものがSnowflakeのdbt開発スキーマに作られます。

Omniでブランチを切ってDynamic Schemaでdbtの開発環境を参照しながら修正
次に、Omniで影響のあるShared Modelにてブランチを切ります。(ちなみに、dbtとOmniは別のGitHubリポジトリと連携させています。)

まず、Refresh Schemaを行って、dbt側の最新のスキーマ構成をOmniのSchema Modelに反映させます。

その後、上部のブランチ名の横にあるdbtのアイコンを押して、dbtの開発環境のEnvironmentに切り替えます。

dbtの開発環境のEnvironmentに切り替えた上で対象のviewファイルを見ると、ordered_atが消えて、purchased_atが入っていることがわかります。

また、dbtの開発環境のEnvironmentに切り替えた上でダッシュボードを見ると、元々ordered_atというカラムで定義していたため、ダッシュボードでこれらのカラムを使っている場合エラーとなります。これはブランチを切っている状態のため、公開済のダッシュボードはdbtの本番環境のEnvironmentを参照しているためエラーは起きていません。
- ブランチを切ってdbtの開発環境を参照している状態:エラーになる

- ブランチでの作業をExitした場合(公開中のダッシュボード):エラーになっていない

改めて作成したブランチに切り替えて、Shared ModelのIDEに移動し、Content Validatorを立ち上げます。すると、下図のようにフィールドの参照が合わないことでエラーが検知されます。

Replaceを押して、FIELDに対して置換を実施します。

この状態でダッシュボードをもう一度表示すると、無事に参照先のフィールドが置き換わって、ブランチで作業をしているけれども先程とは変わってグラフが正しく表示されていることがわかります。これで一連の開発・修正は完了となります。

dbtでmainブランチへのプルリクエスト発行&マージ~dbtの本番環境へdbt build実行
dbt側でコミットしてプルリクエストを発行し、mainブランチにマージして、dbtの本番環境に対してdbt buildを実行します。



これで、Snowflakeのdbt本番スキーマに対して、purchased_atカラムが追加されました。

Omniでmainブランチへのプルリクエスト発行&マージ
最後に、Omniでmainブランチへのプルリクエスト発行&マージを行います。
まず、Omni上でのEnvironmentをdbtの本番環境に戻す必要があります。これを行ってからプルリクエストを発行しないと、このShared Modelを使用するOmniの全ダッシュボードが開発環境を参照するようになってしまうため、注意しましょう。(Environmentが開発環境の状態でプルリクエストを発行しようとすると、Omniの画面で警告も表示されます。)

次に、Sync dbt metadataを実行します。(これをしないと、Environmentが本番環境を指定しているときのviewファイルの定義が古いままでした。)

この上で、対象のviewファイルを見てみると、ordered_atが消えて、purchased_atが入っていることがわかります。

また、Environmentが本番環境を指定している状態で対象のダッシュボードを見ると、問題なくグラフが表示されていることがわかります。(グラフの形が最初と異なっているのは、使用しているdbtのロジックの問題なのでお気になさらず…)

これで問題ないことが確認できたので、Environmentが本番環境を指定している状態でプルリクエストを発行します。(コードが何も変わっていないとプルリクエストが発行できないため、適当なviewファイルのdescriptionなどでスペースなど入れておきます。)


プルリクエストをマージ後、ブランチを切っていた状態から通常の状態に戻して対象のダッシュボードを確認してみると、無事にエラーなくダッシュボードが表示されました!これで、Omniですでに参照しているdbtのModelのフィールド定義を変更する一連の開発の流れは完了となります。

所感
Omniでdbtの開発環境のデータを参照しながらSemantic Layerの定義変更・ダッシュボード修正が行える「Dynamic Schema」を試してみました。ドキュメントを見たときから「これは!?」と感じていたのですが、やはりとても熱い機能でしたね!dbtだけでなくOmniのダッシュボードまで考慮してGitを用いた開発が行えるのはとても良いと思います。
一方で、現段階では以下のことが気になりました。これが改善されれば本当に最高のdbt + BIの開発体験が出来ると思うので、期待したいところです!
- Omniで定義するdbtのEnvironmentにおいて、ユーザー属性を入れることができないこと。つまり、dbt_ssagaraみたいな個人専用スキーマで行うには人数分のEnvironmentを追加する必要がある。(これを嫌う場合には、developブランチやstagingブランチみたいな、mainブランチとの間に1つブランチを入れて、そのブランチでOmniのEnvironmentを定義する必要がある。)
- データベースレベルでユーザー属性に応じた動的な参照データベース変更機能はすでにOmniにあるため、これはアップデートを期待したいです!
- Content Validatorで対象となっているダッシュボードの各グラフからviewの参照定義がコード化されていないため、今回行ったようにdescriptionに半角スペースを追加しないと、最後のOmniからのプルリクエスト発行&マージができなかったこと
- dbtで本番環境に対してdbt buildを行った後、Omni側でdbtの本番環境のスキーマ更新とContent Validatorの内容を反映させるためのプルリクエスト発行&マージが必要なため、dbt側のフィールド変更など行っているとOmniの公開ダッシュボードが正しいフィールドを参照できず、一時的にダウンタイムが発生してしまうこと
- これはもっとスムーズな方法があるかもしれませんが…







