Dataformの環境構築してみた① ~ ワークスペースの作成 ~

## はじめに

Dataformに関連して、GitHub Actionsを使ったデプロイフローの構築や、複数プロジェクトにまたがる開発環境と本番環境の設定を行ってみました。

この具体的な実装方法を、以下の3つの記事に分けて共有したいと思います。

1. Dataformの環境構築してみた① ~ Dataformのワークスペースの作成 ~
2. Dataformの環境構築してみた② ~ GitHub Actionsを使ったコンパイル ~
3. Dataformの環境構築してみた③ ~ 開発環境と本番環境の構築（マルチプロジェクト） ~

Dataformの導入を検討している方や、マルチプロジェクト環境での運用を考えている方の参考になれば幸いです。

## 作るもの

3つの記事を通して、以下に示す開発&適用&パイプライン実行の流れを実現しようと思います。

```mermaid
flowchart TB

featureDataformWorkspace(Dataform\nワークスペース)

featureDataformWorkspace -->|修正をPush| feature["ブランチ\nfeature"]

subgraph Github
    feature --> |"PR適用"| dev["ブランチ\ndev"]
    dev --> |"PR適用"| prod["ブランチ\nprod"]

    dev --->|"pushをトリガーに\nGithubAction起動"| 開発環境用のGithubAction["GithubAction\ndev.yaml"]
    prod -->|"pushをトリガーに\nGithubAction起動"| 本番環境用のGithubAction["GithubAction\nprod.yaml"]
end

開発環境用のGithubAction --> |コンパイル| devDataformComp
本番環境用のGithubAction --> |コンパイル| prodDataformComp

subgraph 開発用GoogleCloud
	devDataformComp[Dataform\nコンパイル結果]:::dev
    -->|定期的に\nテーブルの作成/更新| devBQ[BigQuery\nテーブル]:::dev
end

subgraph 本番用GoogleCloud
	prodDataformComp[Dataform\nコンパイル結果]:::dev
	-->|定期的に\nテーブルの作成/更新| prodBQ[BigQuery\nテーブル]:::prod
end
```

開発環境と本番環境ともに、

| first_name | family_name |
|:-:|:-:|
| 太郎 | 山田  |

というテーブルを、

| full_name |
|:-:|
| 山田 太郎  |

に変換するという単純な処理をサンプルとして実現します。

## ワークスペース作成手順

### BigQueryにテーブル作成

Dataformから参照予定のテーブルをBigQueryに作成します。

まずは、BigQueryのデータセットを作成します。

![Screenshot 2024-10-10 at 8.13.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/dbf14daa-1fa8-e41b-43ef-54ccb3143f11.png)

次に、以下のコマンドでCSVファイルを作成し、BigQueryにアップロードします。
```bash
echo "太郎,山田" > ~/Desktop/temp.csv
```
![Screenshot 2024-10-10 at 8.16.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/cd0b0841-6096-e7b1-310e-c3b4bf7cdcb1.png)

アップロード後、以下のようにテーブルが作成されていることを確認します。
![Screenshot 2024-10-14 at 16.17.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/a6e1c951-39f5-ab65-3a85-4273f8c082de.png)


### Dataform レポジトリ作成

SQLワークフローなどを格納するレポジトリを、Dataformの画面から作成します。
![Screenshot 2024-10-14 at 15.12.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/d0d08241-e7ee-2912-d5d2-bdeb334f3e50.png)

最初のレポジトリを作成すると、ワークフロー実行時などに利用されるサービスアカウントが自動で作成されます。
Dataformによって作られるデフォルトのサービスアカウントは、`service-<プロジェクトの番号>@gcp-sa-dataform.iam.gserviceaccount.com`です。
そのサービスアカウントに、以下のように権限を割り当てます。

![Screenshot 2024-10-14 at 15.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/74b171ff-2563-84b4-2b9d-2b4e3b5f5a62.png)


### Dataform ワークスペース作成

作成したレポジトリの詳細画面を開き、以下のようにワークスペースを作成します。
ワークスペースとは、Gitでいうとfeatureブランチのようなものです。
新しい機能を開発する際には、ワークスペースを使って開発&検証していきます。

![Screenshot 2024-10-08 at 12.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/4386c593-515b-37d7-c9f1-1c69451d23c0.png)
![Screenshot 2024-10-08 at 12.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/9c737569-eca5-a21d-0b5d-5a6da76e617c.png)
![Screenshot 2024-10-08 at 12.15.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/2963bcb2-578f-01da-1b7b-5ab8615a5775.png)

次に、レポジトリの「Settings」でスキーマの接尾辞に「${workspaceName}」を設定します。
こうすることで、ワークフロー実行時にワークスペース名が接尾辞として追加されたデータセットが作成され、各ワークスペースの実行結果が混在しないように設定できます。

![Screenshot 2024-10-14 at 15.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/3e51b94d-7928-29b8-cecc-96fcd41a6d12.png)

![Screenshot 2024-10-14 at 15.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/eb72ff93-ab23-8e84-5ff9-0b8495c67ec0.png)

作成したワークスペースの詳細画面に移動すると表示される「ワークスペースを初期化」というボタンを押して、ワークスペースを初期化しましょう。
デフォルトでいくつかのファイルが作成されます。

![Screenshot 2024-10-08 at 12.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/a03aac80-a354-230e-b536-caff8eca6ae7.png)
![Screenshot 2024-10-10 at 8.34.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/15405d44-8e23-d067-0a13-7b0e3eab889f.png)

### Dataform ソースコード記載

ワークスペース初期化時に作成された以下のファイルは不要なので削除します。

- `/definitions/first_view.sqlx`
- `/definitions/second_view.sqlx`

次に、`/definitions/sources.js`を作成し、データ取得元となるテーブルを定義します。

```js
declare({
    database: "Google Cloudのプロジェクト名",
    schema: "dataset1",
    name: "names",
})
```

`/definitions/fullnames.sqlx`を作成し、以下のようにSQLワークフローを定義します。

```sql
config {
    type: "table"
}


SELECT
  CONCAT(family_name, ' ', first_name) AS fullname
FROM
  ${ref('names')}
```

### 動作確認

「実行を開始」から「All ACTIONS」を選択し、処理を実行します。
![Screenshot 2024-10-08 at 12.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/79c5dab1-5fc9-adc0-6db1-b40d98bf85bc.png)

![Screenshot 2024-10-14 at 16.45.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/e736295c-ade7-cbae-8e96-4c99ce01163d.png)

実行結果として、BigQueryに「fullnames」というテーブルが作成されます。

![Screenshot 2024-10-10 at 8.43.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602115/a7690f0c-00c6-9adb-dc54-b6654dbec44e.png)

## 参考

- https://cloud.google.com/dataform/docs?hl=ja