15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

BigQueryのローカル検証用にbigquery-emulatorを触ってみた。ついでにPythonから接続してみる

Posted at

はじめに

みなさん、BigQueryが絡む処理のローカル開発やテストどうしてますか?BigQueryは公式のエミュレーターが提供されていないのでけっこう困ること多いんじゃないでしょうか?

私はとりあえず、ローカルではなく専用の環境を用意してそこに接続する形にしていましたが、業務委託の方などに入っていただくことが増えると権限周りで少々悩ましいことも多いです。

ただ数ヶ月前に、goccyさんという方が開発されたGo製のOSSbigquery-emulatorが公開され、こうした問題に解消の兆しが見えてきました。(開発者の方にはリスペクトしかありません!)

少し前までは提供されていない機能も多かったのですが、開発が進み環境が整ってきているようなので、今回はこのbigquery-emulatorを触ってみようと思います。

実行準備

今回は提供されているdockerイメージを利用して作業をしていくので、リポジトリのクローンは不要です。

※ docker, docker-composeを利用できるようにしておいてください

環境

  • OS: macOS Big Sur(11.1)

やってみる

CLIからのクエリ実行

まずは起動 -> CLIからのクエリ実行を確認します。

ディレクトリ構成は以下の通りです。

.
├── docker-compose.yaml
└── testdata
    └── data.yaml

ここだけであればcomposeは必須でないですが、後でpythonコンテナから接続したいのでcomposeを利用しています。

中身は以下の通り

docker-compose.yaml
version: '3.7'
services:

    bq:
        image: ghcr.io/goccy/bigquery-emulator:latest
        ports:
            - "9050:9050"
        volumes:
            - ./testdata:/testdata
        command: "bigquery-emulator --project=test --data-from-yaml=../testdata/data.yaml"

./testdata/data.yamlには起動時に挿入するデータを指定しておきます。(これはリポジトリのものをそのまま拝借)

data.yaml
projects:
- id: test
  datasets:
    - id: dataset1
      tables:
        - id: table_a
          columns:
            - name: id
              type: INTEGER
            - name: name
              type: STRING
          data:
            - id: 1
              name: alice
            - id: 2
              name: bob

コンテナを立ち上げれば9050番ポートでbigquery-emulatorが起動し、testという名前のプロジェクト名でdata.yamlに記述したデータについてクエリをかけられるようになるので確認してみましょう!

以下、ターミナルから実行します。

# 起動
$ docker-compose up -d

# クエリ
$ bq --api http://0.0.0.0:9050 query --project_id=test "SELECT id, name FROM dataset1.table_a WHERE id = 1"

+----+-------+
| id | name  |
+----+-------+
|  1 | alice |
+----+-------+

無事にクエリ結果が得られました。

pythonクライアントからのクエリ実行

ここまででもローカルで実行できることに感動ものなのですが、せっかくなのでpythonからも接続してみます。

pythonコンテナ用にDockerfileを追加し、docker-compose.yamlを修正します。
Dockerfileでは、BigQueryのクライアントをインストールしておきます。

$ touch Dockerfile
FROM python:3.8

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install google-cloud-bigquery

COPY app app
WORKDIR /app
docker-compose.yaml
version: '3.7'
services:

    # 追記
    app:
        restart: always
        build: .
        tty: true
        volumes:
            - ./app:/app

.
.
.

pythonで実行するコードはapp/main.pyに以下の通り追加します。

$ mkdir app
$ touch app/main.py
main.py
from google.cloud import bigquery
from google.auth.credentials import AnonymousCredentials


project_id = "test"
client = bigquery.Client(
    project=project_id,
    credentials=AnonymousCredentials(),
    client_options={
        "api_endpoint": "http://host.docker.internal:9050",
    }
)

table_name = f"{project_id}.dataset1.table_a"

query = f'''
SELECT id, name FROM `{table_name}`
'''
result = client.query(query)
for row in result:
    print(row)

AnonymousCredentialsはエミュレーターなどのためにダミーで渡すことのできるcredentialsクラスで、こうしておくことで認証情報を渡さずに認証部分を突破できます。

また今回はコンテナ間で接続するので、エンドポイントがhttp://host.docker.internal:9050になる点にも注意してください。

それではコンテナをbuildしてから実行してみます。

$ docker-compose build --no-cache
$ docker-compose up -d

# 実行
$ docker-compose exec app python main.py

以下の通りクエリ結果が得られました。

Row((1, 'alice'), {'id': 0, 'name': 1})
Row((2, 'bob'), {'id': 0, 'name': 1})

最後に

今回はbigquery-emulatorを少し触ってみました。
すでにおおよそ整備されているので非常に簡単に扱えそうですね!感謝!

これを機にローカル開発環境やテスト環境を本格的に整備して行こうかなーなど考えてます。

というわけで今回はこれにて!

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?