この記事の目的
Dataform をローカルでの開発に変更し、Gemini CLI を活用するためのステップを示すこと
背景
Google Cloud の Dataform を使っているのですが、コンソール画面だけだと以下のような点で非効率性を感じていました。
- コンソール画面自体が若干イケていない (Commit の後、一定時間次の Commit ができないなど)
- データの確認で BigQuery と行き来する
- Gemini に頼りたい時にも、ブラウザなどとの行き来が多く、かつファイルやスキーマのインプットが面倒
やったこと
- Dataform をローカル開発に変えた
- Gemini CLI を活用できるように初期設定した
内容
Dataform セットアップ
もともと既存で Dataform を使っていて Git 管理している場合
もともと既存で Dataform を使っており、Git と連携をしていたので、そのレポジトリをローカルに Clone
git clone https://github.com/xxx/xxx
Local に dataform をインストール
npm i -g @dataform/cli@^3.0.0-beta
dataform install
Dataform の認証設定
dataform init-creds
.df-credentials.json
というファイルが作られたら、.gitignore に追記しておきます。
既存のファイルをコンパイルしてみる。以下のように出れば成功です。
% dataform compile
Compiling...
Compiled 1 action(s).
1 dataset(s):
dataform.example [view]
ちなみに Local に入れてから気づいたのですが、クラウド上で Dataform を Git 連携している場合、デフォルトだと dataform.json
というファイルが Git にあがっています。
ここには dataform が利用する default のロケーションなどの情報があるのですが、
その中に defaultDatabase
というのがいて、BigQuery の場合はここに Project 名が記載されてしまっていいます。
Private Repository で Project ID 程度なら問題ないという考え方もありますが、厳密にやるなら Cloud 側でも .gitignore に記載しておきましょう
新しくローカルで Dataform を使い始める場合
その場合は 公式ページに従えばよいですが、念の為ここにも記載しておきます。
Local に dataform をインストール
npm i -g @dataform/cli@^3.0.0-beta
dataform install
Dataform の認証設定
dataform init-creds
.df-credentials.json
というファイルが作られたら、.gitignore に追記しておきます。
echo "".df-credentials.json" >> .gitignore
Dataform の初期化。$project_name にはプロジェクト名を、region の部分には Dataform が BigQuery にデータを書き込むリージョン(東京の場合は asia-northeast1) を記載します。
dataform init . $projet_name $region
テストファイルを作ります。シンプルですが、type で VIEW であることを示し、その後にクエリを書きます。
echo "config { type: 'view' } SELECT 1 AS test" > definitions/example.sqlx
既存のファイルをコンパイルしてみる。以下のように出れば成功。
% dataform compile
Compiling...
Compiled 1 action(s).
1 dataset(s):
dataform.example [view]
Local での Dataform の実行
セットアップができたら、実行していきます。ここからは新しく Local で実施する場合も、Cloud から Local に移す場合も共通の手順となります。
まず、一旦ファイルを整形します。コンソール上だと Format というボタンを押すとできるのですが、ローカルだとコマンドで行うことになります。
都度実施してもいいですが、Git の Commit 後やファイルの保存後に自動で実行されるように仕込んでおくのもよいでしょう。
dataform format
一度 dry run してみましょう。 dry run では実際には Table や View は作られません。作成した内容が問題ないかなどをチェックする目的で実行します。
% dataform run --dry-run
Compiling...
Compiled successfully.
Dry running (no changes to the warehouse will be applied)...
Table dry run success: dataform.example [view]
ドライランに成功したら、実際に実行してみます。
% dataform run
Compiling...
Compiled successfully.
Running...
Table created: dataform.example [view]
jobId: dataform-ab956513-0efa-4e3e-ba4f-7fxxxxx,
Bytes billed: 0 B
Table と記載されましたが、実際に作られたのは View です。
.df-credentials.json
に記載された projectId や location でデータが作られたことを確認します。
またこのとき、直接 BigQuery を Console で確認してもいいですが、折角なのでコマンドでやってみます。
% bq query --nouse_legacy_sql \
'SELECT
COUNT(*)
FROM
`project_id`.dataform.example'
+-----+
| f0_ |
+-----+
| 1 |
+-----+
これで Dataform の設定は完了です。
なお、Dataform の実行はファイル単位でもできます。
dataform run --actions example
複数の場合は以下。
dataform run --actions example1,example2
また、ファイル同士の依存関係を定義した場合、以下でそれらも考慮して実行されます。
依存関係 (Upstream) も含めて実行したいときは以下。
dataform run --actions example --include-deps
依存している処理 (Downstream)も含めて実行したい場合は以下。
dataform run --actions example --include-dependents
これで Console 上でできることはほぼできることを確認できました。
ただし、Compile Graph という、依存関係をグラフィカルに表示してくれる機能はできません。
公式も推奨する Extention を入れれば出来るのですが、個人的に信頼度の検証ができていないので入れていません。
テーブルが多くてそもそも依存関係の表示をそんなにやってこなかったので、
なお公式はメンテ終了しています。ただ SQLX の色付けとかぐらいはしてくれてるので、ここは若干リスクを覚悟ですがそちらは入れています。
Gemini CLI の設定
導入方法の最新版はGitHubを参照してもらうのが良いですが、
執筆時点では以下でインストールできます。
npm install -g @google/gemini-cli
起動には以下で、初回起動時には諸々設定が走ります。
gemini
Gemini CLI を使えば、Dataform の SQL ファイルなどを @ で参照しながら Gemini と対話したりできます。
これができるだけでも、Dataform を Local に移した価値があるのですが、折角なので以下を試しました。
> @definitions/example.sqlx で作られた View を表示して │
╰──────────────────────────────────────────────────────────╯
すると以下のように表示されます。色々やりとりが発生してなかなか期待する答えがすっと出ません。
✦ 承知いたしました。
@definitions/example.sqlxのconfigブロックを除いた部分が、ビューの定義そのものになります。
1 SELECT
2 1 AS test
╭───────────────────────────────────────╮
│ > BigQuery 側の実データを表示してよ │
╰───────────────────────────────────────╯
✦ 大変申し訳ありませんが、繰り返しになりますが、私にはBigQueryに直接アクセスして実データを表示する権限や機能がありません。
そのため、お客様の環境で実行された結果を私に提供していただかない限り、BigQuery上のデータを表示することはできません。
お手数ですが、BigQueryのコンソール画面やbqコマンド等でクエリを実行し、その結果をこちらに共有していただけますでしょうか。
そこで以下のように伝えました。
> @definitions/example.sqlx から bq コマンド作って実行したら良いじゃん │
╰──────────────────────────────────────────────────────────────────────────╯
✦ おっしゃる通り、それが理想的な流れです。しかし、bqコマンドを実行するためには、対象のビューがどのGoogle Cloudプロジェクトの、どのBigQueryデータセットに存在するかを指定する必要があります。
具体的には、以下のような情報がコマンドに必要です。
* プロジェクトID
* データセットID
これらの情報はdefinitions/example.sqlxファイル内には記述されておらず、お客様の環境に依存するため、私には知ることができません。
もし、プロジェクトIDとデータセットIDを教えていただければ、私がbqコマンドを作成します。あるいは、以下のテンプレートの [] 部分を埋めて実行していただくことも可能です。
1 bq query --project_id [プロジェクトID] "SELECT * FROM [データセットID].example LIMIT 10"
Using: 1 GEMINI.md file | 1 MCP server (ctrl+t to view)
詳細は省きますが、このあと プロジェクトID とデータセットID を与えたのですが、一度クエリに失敗し、最終的に --use_legacy_sql=false
をつけるところを Gemini CLI が判断して、成功しました。
ということで、これを毎回戦ってても時間もトークンももったいないので、次回以降すっと実行できるように GEMINI.md
を設定しました。
なお、BigQuery を叩くタイミングで、認証系のエラーが出た方もいるかもしれません。その場合は以下のコマンドなどを打って、認証アカウントを紐づけておきます。
$ gcloud auth login
Gemini.md の設定
GEMINI.md
は、Gemini CLI がユーザからのクエリに対応する際に参照してくれるもので、
上記のような複雑な処理について、手順を書いておくことでより期待する効果にたどり着きやすくなります。
# Dataformで作成したテーブルをBigQueryでクエリする方法
この記事では、Dataformプロジェクトで定義したテーブルに対して、`bq`コマンドラインツールを使いBigQueryから直接クエリを実行する手順を解説します。また、その過程で発生しがちな一般的なエラーへの対処法も紹介します。
## 1\. 完全なテーブル名を特定する
テーブルにクエリを実行する前に、まずは`project_id.schema_name.table_name`という形式の完全なテーブル名を特定する必要があります。
### プロジェクトID
Google CloudのプロジェクトIDは、ご自身のプロジェクトのものを使用してください。ここでは例として`your-project-id`とします。
### スキーマ名とテーブル名
```
スキーマ名とテーブル名は、`definitions/`ディレクトリにある対応する`.sqlx`ファイルの`config`ブロック内で定義されています。
1. クエリを実行したいテーブルの`.sqlx`ファイルを探します。
2. ファイル冒頭の`config`ブロックを確認します。
例えば、`definitions/sales/daily_summary.sqlx`というファイルの場合、`config`ブロックは以下のようになっています。
```sql
config {
type: "table",
schema: "sales",
name: "daily_summary"
}
```
この定義から、以下の情報を読み取れます。
- **スキーマ:** `sales`
- **テーブル名:** `daily_summary`
もし`config`ブロックに`schema`の指定がない場合、Dataformは`dataform.json`で定義されている`defaultSchema`(デフォルトでは`dataform`)を使用します。
この例における完全なテーブル名は `your-project-id.sales.daily_summary` となります。
## 2\. `bq`コマンドでクエリを実行する
完全なテーブル名がわかったら、`bq`ツールを使ってクエリを実行します。
### 素早く中身を確認する場合: `bq head`
テーブルの構造や最初の数行を素早くプレビューしたい場合は、`bq head`コマンドが便利です。シンプルで、シェルのクォーテーション問題を回避しやすい利点があります。
**コマンド:**
```sh
bq head -n 100 <project_id>:<schema>.<table_name>
```
**実行例:**
```sh
bq head -n 100 your-project-id:sales.daily_summary
```
### クエリを実行する場合: `bq query`
完全な`SELECT`文を実行する必要がある場合は、`bq query`コマンドを使用します。
#### よくある落とし穴
- **バッククォートの問題:** `bq query`コマンド内でテーブル名をバッククォート(例: `` `your-project-id.sales.daily_summary` ``)で囲むと、一部のシェルではコマンド置換エラーが発生することがあります。可能な限り避けるのが無難です。
- **ハイフンの問題:** プロジェクトIDに含まれるハイフン(例: `your-project-id`)がマイナス記号として解釈され、クエリの解析エラーを引き起こすことがあります。
#### 推奨される解決策
最も確実な方法は、`--use_legacy_sql=false`フラグを使用することです。これにより標準SQLが有効になり、`bq`ツールがバッククォートなしでテーブル名を正しく解析できるようになります。
**コマンド:**
```sh
bq query --project_id=<project_id> --use_legacy_sql=false "SELECT * FROM <project_id>.<schema>.<table_name> LIMIT 100"
```
**実行例:**
```sh
bq query --project_id=your-project-id --use_legacy_sql=false "SELECT * FROM your-project-id.sales.daily_summary LIMIT 100"
```
この手順に従うことで、Dataformプロジェクトで定義された任意のテーブルに確実かつ安全にクエリを実行できます。
もう少し簡潔にかけそうな気もしますが、上記のように記載をしておけばOKです。
では次のように実行してみます。GEMINI.md に書きたくない場合は Project 名をいれる必要がありますが、予め書いておくか、または最初にクエリを入力する時に合わせて与えてやれば一回往復を減らすこともできます。
╭──────────────────────────────────────────────────────────────────╮
│ > @definitions/example.sqlx によって作られたVIEW を Query して │
╰──────────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────────────────╮
│ ✔ ReadManyFiles Will attempt to read and concatenate files using patterns:… │
│ │
│ │
│ ### ReadManyFiles Result (Target Dir: `/Users/shohei/Dev/test`) │
│ │
│ Successfully read and concatenated content from **1 file(s)**. │
│ │
│ **Processed Files:** │
│ - `definitions/example.sqlx` │
╰───────────────────────────────────────────────────────────────────────────────────╯
✦ 承知いたしました。definitions/example.sqlxから作成されたビューにクエリを実行します。
まず、dataform.jsonファイルがあるか確認し、デフォルトのスキーマ名を取得します。
╭───────────────────────────────────────────────────────────────────────────────────╮
│ ✔ FindFiles 'dataform.json' │
│ │
│ No files found │
╰───────────────────────────────────────────────────────────────────────────────────╯
✦ dataform.jsonが見つかりませんでしたので、デフォルトのスキーマdataformを使用します。
クエリを実行するために、Google CloudのプロジェクトIDを教えていただけますか?
╭────────────────────────╮
│ > (Projet 名を入力) │
╰────────────────────────╯
✦ ありがとうございます。プロジェクトID shohei-tech-school を使用して、ビュー dataform.example
にクエリを実行します。
╭─────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✔ Shell bq query --project_id=shohei-tech-school --use_legacy_sql=false "SELECT * FROM s… │
│ │
│ +------+ │
│ | test | │
│ +------+ │
│ | 1 | │
│ +------+ │
╰─────────────────────────────────────────────────────────────────────────────────────────────╯
✦ クエリが正常に実行され、結果が表示されました。
他に何かお手伝いできることはありますか?
Using: 2 GEMINI.md files | 1 MCP server (ctrl+t to view)
これで、Gemini CLI 経由で Dataform と BigQuery を一気通貫で行き来できるようになりました。
まとめ
Dataform をローカルで動かす方法と、Gemini CLI と連携する方法を解説しました。