Overview
Go で BigQuery (以下 BQ) のクライアントの実装して返されたクエリの結果を Entity に Unmarshal する方法について調べたのでその備忘録です。
Note
結論から言ってしまうと自前でゴリゴリ型指定して Unmarshal するよりも BQ の package に BQ のデータ型の定義があるのでこれを参考にすると良さそうです。
// Each BigQuery column type corresponds to one or more Go types; a matching struct // field must be of the correct type. The correspondences are: // // STRING string // BOOL bool // INTEGER int, int8, int16, int32, int64, uint8, uint16, uint32 // FLOAT float32, float64 // BYTES []byte // TIMESTAMP time.Time // DATE civil.Date // TIME civil.Time // DATETIME civil.DateTime // // A repeated field corresponds to a slice or array of the element type. A STRUCT // type (RECORD or nested schema) corresponds to a nested struct or struct pointer. // All calls to Next on the same iterator must use the same struct type. // // It is an error to attempt to read a BigQuery NULL value into a struct field, // unless the field is of type []byte or is one of the special Null types: NullInt64, // NullFloat64, NullBool, NullString, NullTimestamp, NullDate, NullTime or // NullDateTime. You can also use a *[]Value or *map[string]Value to read from a // table with NULLs.
ref: https://github.com/googleapis/google-cloud-go/blob/v0.46.3/bigquery/iterator.go#L83-L104
特に以下の部分
It is an error to attempt to read a BigQuery NULL value into a struct field, unless the field is of type byte or is one of the special Null types: NullInt64, NullFloat64, NullBool, NullString, NullTimestamp, NullDate, NullTime or NullDateTime. You can also use a Value or map[string]Value to read from a table with NULLs.
カラムによっては NULL のケースもあると思うので以下のように BQ での NULL を安全に処理する型が用意されているのは助かります。
type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL. }
最初自前でEntity の定義をして時刻型や INTERGER あたりでデバックしながら進めてたんですが、カラム数が多いとカラムによってあったりなかったりする(= Null の扱い) のが面倒だったりそこそこなデータ量のクエリ叩くのでお金の不安もあり、ミスるとやり直してたりして辛かったのですが、GoDoc 眺めに行ったら一発で解決しました。