Protobuf 列としてデータをエクスポートする
このドキュメントでは、BigQuery のユーザー定義関数(UDF)を使用して、BigQuery データをプロトコル バッファ(Protobuf)列としてエクスポートする方法について説明します。
Protobuf 列を使用する場合
BigQuery には、選択したデータをフォーマットするための組み込み関数がいくつか用意されています。1 つの方法は、複数の列の値を 1 つの Protobuf 値に統合することです。これには次の利点があります。
- オブジェクト タイプの安全性を確保できる。
- JSON と比較して圧縮、データ移転時間、費用が改善されている。
- 多くのプログラミング言語に Protobuf を処理するためのライブラリがあるため、柔軟性がある。
- 複数の列から読み取り、1 つのオブジェクトを構築する場合のオーバーヘッドが少ない。
他の列型でも型の安全性を確保できますが、Protobuf 列を使用すると完全型オブジェクトが提供されるため、アプリケーション レイヤやパイプラインの別の部分で行う必要がある作業の量を減らすことができます。
ただし、BigQuery データを Protobuf 列としてエクスポートするには制限があります。
- Protobuf 列は、適切にインデックスに登録されず、フィルタされません。Protobuf 列の内容で検索すると、効果が下がる可能性があります。
- Protobuf 形式でのデータの並べ替えは困難な場合があります。
これらの制限がエクスポート ワークフローに適用される場合は、BigQuery データをエクスポートするための他の方法を検討することをおすすめします。
EXPORT DATA
ステートメントでスケジュールされたクエリを使用して、エクスポートされた BigQuery データを日時で並べ替え、定期的なエクスポートをスケジュールする。BigQuery は、Avro、CSV、JSON、Parquet 形式へのデータのエクスポートをサポートしています。- Dataflow を使用して、Avro または CSV ファイル形式で BigQuery データをエクスポートする。
必要なロール
BigQuery データを Protobuf 列としてエクスポートするために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
- ユーザー定義関数を作成する: BigQuery データ編集者(
roles/bigquery.dataEditor
) - BigQuery テーブルからデータをエクスポートする: BigQuery データ閲覧者(
roles/bigquery.dataViewer
) - ファイルを読み取って Cloud Storage にアップロードする: Storage オブジェクト作成者(
roles/storage.objectCreator
)
ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
UDF を作成する
BigQuery の STRUCT
データ型を Protobuf 列に変換する UDF を作成します。
コマンドラインで、
bigquery-utils.git
リポジトリのクローンを作成します。git clone https://github.com/GoogleCloudPlatform/bigquery-utils.git
Protobuf エクスポート フォルダに移動します。
cd bigquery-utils/tools/protobuf_export
cp
コマンドまたはオペレーティング システムのファイル ブラウザを使用して、proto ファイルを./protos
子フォルダにコピーします。./protos
フォルダには、dummy.proto
という名前のサンプル proto ファイルがすでに存在します。必要なパッケージを GitHub リポジトリからインストールします。
npm install
webpack を使用してパッケージをバンドルします。
npx webpack --config webpack.config.js --stats-error-details
./dist
子フォルダでpbwrapper.js
ファイルを見つけて、ファイルを Cloud Storage バケットにアップロードします。[BigQuery] ページに移動します。
クエリエディタを使用して、既存の BigQuery テーブル列から Protobuf 列を作成する
toMyProtoMessage
という名前の UDF を作成します。CREATE FUNCTION DATASET_ID.toMyProtoMessage(input STRUCT<INPUT_FIELDS>) RETURNS BYTES LANGUAGE js OPTIONS ( library=["gs://BUCKET_NAME/pbwrapper.js"] ) AS r""" let message = pbwrapper.setup("PROTO_PACKAGE.PROTO_MESSAGE") return pbwrapper.parse(message, input) """;
次のように置き換えます。
DATASET_ID
: UDF を含むデータセットの ID。INPUT_FIELDS
: proto ファイルの proto メッセージ タイプで使用されるフィールド(field_name_1 field_type_1 [, field_name_2 field_type_2, ...]
形式)。アンダースコアを使用するメッセージ タイプ フィールドは、キャメルケースを使用するように変換する必要があります。たとえば、メッセージ タイプが次のようなものである場合、入力フィールドの値は
itemId int64, itemDescription string
にする必要があります。message ThisMessage { int64 item_id = 1; string item_description = 2; }
BUCKET_NAME
:pbwrapper.js
ファイルを含む Cloud Storage バケットの名前。PROTO_PACKAGE
: proto ファイルのパッケージ。PROTO_MESSAGE
: proto ファイルのメッセージ タイプ。
たとえば、提供されている
dummy.proto
ファイルを使用する場合、CREATE FUNCTION
ステートメントは次のようになります。CREATE OR REPLACE FUNCTION mydataset.toMyProtoMessage(input STRUCT<dummyField STRING>) RETURNS BYTES LANGUAGE js OPTIONS ( library=["gs://mybucket/pbwrapper.js"] ) AS r""" let message = pbwrapper.setup("dummypackage.DummyMessage") return pbwrapper.parse(message, input) """;
Protobuf 値として列をフォーマットする
toMyProtoMessage
UDF を実行して、BigQuery テーブルの列を Protobuf 値としてフォーマットします。
SELECT
UDF_DATASET_ID.toMyProtoMessage(STRUCT(INPUT_COLUMNS)) AS protoResult
FROM
`PROJECT_ID.DATASET_ID.TABLE_NAME`
LIMIT
100;
次のように置き換えます。
UDF_DATASET_ID
: UDF を含むデータセットの ID。INPUT_COLUMNS
: Protobuf 値としてフォーマットする列の名前(column_name_1 [, column_name_2, ...]
の形式)。列には、サポートされているスカラー値型か、ARRAY
やSTRUCT
などのスカラー以外の型を指定できます。入力列は、プロトコル メッセージ タイプ フィールドの型と数と一致している必要があります。PROJECT_ID
: 該当するテーブルが含まれているプロジェクトの ID。データセットが現在のプロジェクトにある場合は、プロジェクトの識別をスキップできます。DATASET_ID
: テーブルを含むデータセットの ID。TABLE_NAME
: 形式設定する列を含むテーブルの名前。
たとえば、dummy.proto
に基づく toMyProtoMessage
UDF を使用する場合、次の SELECT
ステートメントは機能します。
SELECT
mydataset.toMyProtoMessage(STRUCT(word)) AS protoResult
FROM
`bigquery-public-data.samples.shakespeare`
LIMIT 100;
Protobuf 値を操作する
BigQuery データを Protobuf 形式でエクスポートすると、データを完全な型のオブジェクトまたは構造体として操作できるようになります。
次のコードサンプルは、エクスポートされたデータを処理または操作する方法の例をいくつか示しています。