データセットとアクセス権限の確認
データセット一覧の取得
ノートCommand
${PROJECTID} GCPプロジェクト内のBigQueryデータセットを一覧表示するコマンド
bq ls --project_id=${PROJECTID} --max_results=1000Options
glossary:
- def: bq ls
description: |
`ls` は `list` の略.プロジェクト内のデータセット,データセット内のテーブルなどを一覧表示するサブコマンド.
- def: --project_id=${PROJECTID}
description: |
一覧を取得する対象のプロジェクトを指定.省略時は `gcloud` / `bq` のデフォルトプロジェクトが使われる.
- def: --max_results=1000
description: |
返す件数の上限.`bq ls` はデフォルトで最大 50 件しか返さないため,
データセットが多いプロジェクトでは取りこぼしを防ぐために指定する.データセットごとのアクセス権限(ACL)の確認
bq show --format=json の出力の access フィールドに,データセット単位の ACL(ロール × 付与先)が入っている. これを全データセットについてループで取得し,Python で整形する.
整形スクリプト: acl.py
import sys, json
j = json.load(sys.stdin)
print("location:", j.get("location"))
for a in j.get("access", []):
r = a.get("role", "-")
k = [x for x in a if x != "role"][0] # userByEmail / specialGroup / groupByEmail / view など
v = a[k]
print(" %-8s %-14s %s" % (r, k, v if isinstance(v, str) else json.dumps(v)))実行コマンド
for d in $(bq ls --project_id=${PROJECTID} --max_results=1000 | tail -n +3); do
echo "=== $d"
bq show --format=json ${PROJECTID}:$d | python3 acl.py
donetail -n +3でbq lsのヘッダ 2 行(datasetIdと区切り線)を除いている
出力例は以下のようになる.
=== ${DATASET}
location: asia-northeast1
OWNER specialGroup projectOwners
WRITER specialGroup projectWriters
READER specialGroup projectReaders
OWNER userByEmail user-a@example.com
WRITER userByEmail sa-name@${PROJECTID}.iam.gserviceaccount.com
プロジェクトレベルの IAM ポリシーの確認
データセット ACL の specialGroup(projectOwners / projectWriters / projectReaders)が 実際に誰を指すかは,プロジェクトの IAM を見ないと分からない. BigQuery 関連ロールと基本ロールに絞って取得する.
gcloud projects get-iam-policy ${PROJECTID} --format=json | python3 -c '
import sys, json
p = json.load(sys.stdin)
for b in p.get("bindings", []):
if "bigquery" in b["role"] or b["role"] in ("roles/owner", "roles/editor", "roles/viewer"):
print(b["role"])
for m in b["members"]:
print(" ", m)'specialGroup とプロジェクトロールの対応は以下.
| データセット ACL のロール | specialGroup |
対応するプロジェクトのロール |
|---|---|---|
| OWNER | projectOwners |
roles/owner |
| WRITER | projectWriters |
roles/editor |
| READER | projectReaders |
roles/viewer |
ヒント結果を読むときのポイント
- プロジェクトの
roles/editorやroles/bigquery.dataEditorを持つユーザーは, データセット ACL に個別付与がなくても全データセットに書き込める - 逆に,プロジェクトロールを持たないユーザーでも,データセット ACL への個別付与だけで そのデータセットのオーナーになっていることがある
roles/bigquery.dataOwnerをプロジェクトレベルで持つサービスアカウント(例: Looker Studio 連携用)は 全データセットに対してオーナー相当になるので,意図した付与か確認する- Workbench などのサービスアカウントは,必要なデータセットにだけ READER / WRITER が付与されているかを確認する
警告この方法で確認できない範囲
- テーブル単位の IAM,行レベルセキュリティ(row access policy),列レベルのポリシータグ
- カスタムロールやその他のロール(上のスクリプトは BigQuery 関連ロールと
owner/editor/viewerに絞っている) - 組織・フォルダから継承される IAM(
gcloud projects get-iam-policyはプロジェクトに直接付いたバインディングのみ返す)
Datasetの作成
ノートCommand
${PROJECTID} GCPプロジェクト内に,${DATASET} という名前のBigQueryデータセットを,東京リージョンに作成するコマンド
bq mk --location=asia-northeast1 --dataset --description="hogehoge" ${PROJECTID}:${DATASET}$PROJECTID: Google Cloud プロジェクトID$DATASET: 作成するデータセット名.英数字とアンダースコアのみ使用可,ハイフン不可
Options
glossary:
- def: bq mk
description: |
`mk` は `make` の略.BigQuery のリソース(データセット,テーブル,ビューなど)を
新規作成するサブコマンド.
- def: --location=asia-northeast1
description: |
データセットを配置するリージョンを指定.`asia-northeast1` は東京リージョン.
一度設定したらデータセット作成後は変更不可の点に注意.BigQuery はクエリ実行時にデータとジョブが同じリージョンにある必要があるため,
ロケーションは慎重に選ぶ.
- def: --dataset
description: |
作成するリソースの種類が「データセット」であることを明示.`bq mk` はテーブルやビューも
作れるため,何を作るかをフラグで指定する.
- def: --description="..."
description: |
データセットの説明文.後から見たときに用途がわかるようメタ情報として付ける.
- def: ${PROJECTID}:${DATASET}
description: |
作成するデータセットの完全修飾名.`プロジェクトID:データセットID` の形式.Dataset Descriptionの変更
方法 1: フラグで直接書き換え
bq update --description="新しい説明文をここに" ${PROJECTID}:${DATASET}方法 2: JSON 経由で編集
長文の説明やラベル等もまとめて編集したい場合は,現在のメタデータを JSON として 取り出して編集する方法が安全.
# 1. 現在の設定をJSONで取得
bq show --format=prettyjson ${PROJECTID}:${DATASET} > dataset.json
# 2. dataset.json の "description" フィールドを編集
# 3. 更新を反映
bq update --source dataset.json ${PROJECTID}:${DATASET}
ヒント
- 方法 1 は単純な上書き向け.改行やクオートを含む長文は方法 2 が確実.
bq showの出力にはlastModifiedTimeなどの読み取り専用フィールドも含まれるが,bq update --source側で無視されるためそのまま編集して問題ない.
テーブルをGCSへエクスポート
ノートCommand
BigQuery テーブルを GCS へ Parquet 形式でエクスポートするコマンド
bq extract \
--destination_format=PARQUET \
'${PROJECTID}:${DATASET}.${TABLE}' \
'gs://${BUCKET}/${TABLE}/*.parquet'${PROJECTID}:${DATASET}.${TABLE}: エクスポート元のテーブルの完全修飾名gs://${BUCKET}/${TABLE}/*.parquet: 出力先 GCS パス.*でシャード分割される
Options
glossary:
- def: bq extract
description: |
BigQuery テーブルの内容を GCS へエクスポートするサブコマンド.
CSV・JSON・Parquet・Avro などの形式に対応.
- def: --destination_format=PARQUET
description: |
出力形式を指定.`PARQUET` のほか `CSV`,`NEWLINE_DELIMITED_JSON`,`AVRO` が使用可能.
Parquet はカラム型フォーマットのため,後続の分析処理での読み込みが高速.
- def: "gs://bucket/path/*.parquet"
description: |
出力先 GCS URI.`*` を含めるとファイルが複数シャードに分割されて書き出される.
テーブルが大きい場合は分割必須(1 ファイルあたり上限 1 GB).
`*` を含めない場合,テーブルサイズが上限を超えるとエラーになる.