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)}
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 FieldType | Google SQL Data Type |
---|---|
STRING | STRING |
BYTES | BYTES |
INTEGER | INTEGER(alias) |
FLOAT | FLOAT64 |
BOOLEAN | BOOLEAN (alias) |
TIMESTAMP | TIMESTAMP |
RECORD | STRUCT |
DATE | DATE |
TIME | TIME |
DATETIME | DATETIME |
NUMERIC | NUMERIC |
GEOGRAPHY | GEOGRAPHY |
BIGNUMERIC | BIGNUMERIC |
INTERVAL | INTERVAL |
JSON | JSON |
RAMGE | RANGE |
RECORD が当然として、FLOAT は FLOAT64 などへの変換が必要になる。INTEGER と BOOLEAN はそれぞれ同名のエイリアスがあるため、そのまま利用できる。
取得したスキーマを元に NULL を挿入するクエリを生成する場合を考える。STRING などの場合は、取得された FieldType をそのまま利用して次のようにすればいい。
fmt.Sprintf("CAST(NULL AS %s) AS %s", fs.Type, fs.Name)
しかし、FLOAT の場合を考慮すると分岐が必要になる。
fieldType := fs.Typeif 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/