400 文字
2 分

BigQueryのフィールド取得とクエリで利用できる型への変換

Table.Metadata 各フィールドのスキーマを取得する#

cloud.google.com/go/bigqueryを利用すると、次のように BigQuery のテーブルのスキーマを取得できる。

md, err := client.Dataset("my_dataset").Table("my_table").Metadata(ctx)
for _, fs := range md.Schema {
fmt.Printf("Name: %s, FieldType: %s\n", fs.Name, fs.Type)
}

https://pkg.go.dev/cloud.google.com/go/bigquery#FieldSchema

FieldType を Google SQL で利用できる型に変換する#

Table.Metadataで取得されるFieldTypeは、BigQuery でフィールドを定義する値であって、Google SQL*で利用できる型とは異なる場合がある。

*Google SQL : BigQuery の SQL は、Google SQL を採用している。

Google SQL の Data types についてのドキュメントを参照して、可能な限り BigQuery FieldType と同名の Google SQL Data Type を選択した変換表は次のようになる。

BigQuery FieldTypeGoogle SQL Data Type
STRINGSTRING
BYTESBYTES
INTEGERINTEGER(alias)
FLOATFLOAT64
BOOLEANBOOLEAN (alias)
TIMESTAMPTIMESTAMP
RECORDSTRUCT
DATEDATE
TIMETIME
DATETIMEDATETIME
NUMERICNUMERIC
GEOGRAPHYGEOGRAPHY
BIGNUMERICBIGNUMERIC
INTERVALINTERVAL
JSONJSON
RAMGERANGE

RECORD が当然として、FLOAT は FLOAT64 などへの変換が必要になる。INTEGER と BOOLEAN はそれぞれ同名のエイリアスがあるため、そのまま利用できる。

取得したスキーマを元に NULL を挿入するクエリを生成する場合を考える。STRING などの場合は、取得された FieldType をそのまま利用して次のようにすればいい。

fmt.Sprintf("CAST(NULL AS %s) AS %s", fs.Type, fs.Name)

しかし、FLOAT の場合を考慮すると分岐が必要になる。

fieldType := fs.Type
if fs.Type == bigquery.FloatFieldType {
fieldType = "FLOAT64"
}
fmt.Sprintf("CAST(NULL AS %s) AS %s", fieldType, fs.Name)

RECORD を考慮する場合は、さらに Field のスキーマを見て、再帰的に処理する必要がある。 例えば、STRING 型の p1 と p2 というフィールドを持つ record_field の場合、次のようなクエリを生成すればいい。

CAST(NULL AS STRUCT<p1 STRING, p2 FLOAT64>) AS record_field
BigQueryのフィールド取得とクエリで利用できる型への変換
https://blog.ohirunewani.com/posts/bigquery-field-get-and-convert-to-query-usable-type/
作者
hrdtbs
公開日
2025-01-04
ライセンス
CC BY-NC-SA 4.0