Documentation ¶
Overview ¶
Package protobq implements saving and loading protobuf messages to and from BigQuery.
Index ¶
- func InferSchema(msg proto.Message) bigquery.Schema
- func Load(bqMessage []bigquery.Value, bqSchema bigquery.Schema, message proto.Message) error
- func Marshal(msg proto.Message) (map[string]bigquery.Value, error)
- func Unmarshal(bqMessage map[string]bigquery.Value, message proto.Message) error
- type MarshalOptions
- type MessageLoader
- type MessageSaver
- type SchemaOptions
- type UnmarshalOptions
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InferSchema ¶
InferSchema infers a BigQuery schema for the given proto.Message using default options.
Example ¶
msg := &library.Book{} schema := protobq.InferSchema(msg) expected := bigquery.Schema{ {Name: "name", Type: bigquery.StringFieldType}, {Name: "author", Type: bigquery.StringFieldType}, {Name: "title", Type: bigquery.StringFieldType}, {Name: "read", Type: bigquery.BooleanFieldType}, } fmt.Println(cmp.Equal(expected, schema))
Output: true
func Load ¶
Load the bigquery.Value list into the given proto.Message using the given bigquery.Schema. It will clear the message first before setting the fields. If it returns an error, the given message may be partially set.
Example ¶
row := []bigquery.Value{ "publishers/123/books/456", "P.L. Travers", "Mary Poppins", true, } schema := bigquery.Schema{ {Name: "name", Type: bigquery.StringFieldType}, {Name: "author", Type: bigquery.StringFieldType}, {Name: "title", Type: bigquery.StringFieldType}, {Name: "read", Type: bigquery.BooleanFieldType}, } msg := &library.Book{} if err := protobq.Load(row, schema, msg); err != nil { // TODO: Handle error. } expected := &library.Book{ Name: "publishers/123/books/456", Author: "P.L. Travers", Title: "Mary Poppins", Read: true, } fmt.Println(cmp.Equal(expected, msg, protocmp.Transform()))
Output: true
func Marshal ¶
Marshal writes the given proto.Message in BigQuery format using default options.
Example ¶
msg := &library.Book{ Name: "publishers/123/books/456", Author: "P.L. Travers", Title: "Mary Poppins", Read: true, } row, err := protobq.Marshal(msg) if err != nil { // TODO: Handle error. } expected := map[string]bigquery.Value{ "name": "publishers/123/books/456", "author": "P.L. Travers", "title": "Mary Poppins", "read": true, } fmt.Println(cmp.Equal(expected, row))
Output: true
func Unmarshal ¶
Unmarshal the bigquery.Value map into the given proto.Message. It will clear the message first before setting the fields. If it returns an error, the given message may be partially set.
Example ¶
row := map[string]bigquery.Value{ "name": "publishers/123/books/456", "author": "P.L. Travers", "title": "Mary Poppins", "read": true, } msg := &library.Book{} if err := protobq.Unmarshal(row, msg); err != nil { // TODO: Handle error. } expected := &library.Book{ Name: "publishers/123/books/456", Author: "P.L. Travers", Title: "Mary Poppins", Read: true, } fmt.Println(cmp.Equal(expected, msg, protocmp.Transform()))
Output: true
Types ¶
type MarshalOptions ¶
type MarshalOptions struct { // Schema contains the schema options. Schema SchemaOptions }
MarshalOptions is a configurable BigQuery format marshaler.
type MessageLoader ¶
type MessageLoader struct { // Options to use for unmarshaling the Message. Options UnmarshalOptions // Message to load. Message proto.Message }
MessageLoader implements bigquery.ValueLoader for a proto.Message. The message is converted from a BigQuery row using the provided UnmarshalOptions.
Example ¶
package main import ( "context" "errors" "fmt" "cloud.google.com/go/bigquery" "go.einride.tech/protobuf-bigquery/encoding/protobq" publicv1 "go.einride.tech/protobuf-bigquery/internal/examples/proto/gen/go/einride/bigquery/public/v1" "google.golang.org/api/iterator" "google.golang.org/protobuf/encoding/prototext" ) func main() { ctx := context.Background() // Read from the public "film locations" BigQuery dataset into a proto message. const ( project = "bigquery-public-data" dataset = "san_francisco_film_locations" table = "film_locations" ) // Connect to BigQuery. client, err := bigquery.NewClient(ctx, project) if err != nil { panic(err) // TODO: Handle error. } // Load BigQuery rows into a FilmLocation message. messageLoader := &protobq.MessageLoader{ Message: &publicv1.FilmLocation{}, } // Iterate rows in table. rowIterator := client.Dataset(dataset).Table(table).Read(ctx) for { // Load next row into the FilmLocation message. if err := rowIterator.Next(messageLoader); err != nil { if errors.Is(err, iterator.Done) { break } panic(err) // TODO: Handle error. } // Print the message. fmt.Println(prototext.Format(messageLoader.Message)) } }
Output:
type MessageSaver ¶
type MessageSaver struct { // Options to use for marshaling the Message. Options MarshalOptions // InsertID governs the best-effort deduplication feature of // BigQuery streaming inserts. // // If the InsertID is empty, a random InsertID will be generated by // this library to facilitate deduplication. // // If the InsertID is set to the sentinel value bigquery.NoDedupeID, an InsertID // is not sent. // // For all other non-empty values, BigQuery will use the provided // value for best-effort deduplication. InsertID string // Message to save. Message proto.Message }
MessageSaver implements bigquery.ValueSaver for a proto.Message. The message is converted to a BigQuery row using the provided MarshalOptions.
Example ¶
package main import ( "context" "flag" "strconv" "cloud.google.com/go/bigquery" "go.einride.tech/protobuf-bigquery/encoding/protobq" publicv1 "go.einride.tech/protobuf-bigquery/internal/examples/proto/gen/go/einride/bigquery/public/v1" ) func main() { ctx := context.Background() // Write protobuf messages to a BigQuery table. projectID := flag.String("project", "", "BigQuery project to write to.") datasetID := flag.String("dataset", "", "BigQuery dataset to write to.") tableID := flag.String("table", "", "BigQuery table to write to.") create := flag.Bool("create", false, "Flag indicating whether to create the table.") flag.Parse() // Connect to BigQuery. client, err := bigquery.NewClient(ctx, *projectID) if err != nil { panic(err) // TODO: Handle error. } table := client.Dataset(*datasetID).Table(*tableID) // Create the table by inferring the BigQuery schema from the protobuf schema. if *create { if err := table.Create(ctx, &bigquery.TableMetadata{ Schema: protobq.InferSchema(&publicv1.FilmLocation{}), }); err != nil { panic(err) // TODO: Handle error. } } // Insert the protobuf messages. inserter := table.Inserter() for i, filmLocation := range []*publicv1.FilmLocation{ {Title: "Dark Passage", ReleaseYear: 1947, Locations: "Filbert Steps"}, {Title: "D.O.A", ReleaseYear: 1950, Locations: "Union Square"}, {Title: "Flower Drum Song", ReleaseYear: 1961, Locations: "Chinatown"}, } { if err := inserter.Put(ctx, &protobq.MessageSaver{ Message: filmLocation, InsertID: strconv.Itoa(i), // include an optional insert ID }); err != nil { panic(err) // TODO: Handle error. } } }
Output:
type SchemaOptions ¶
type SchemaOptions struct { // UseEnumNumbers converts enum values to INTEGER types. UseEnumNumbers bool // UseDateTimeWithoutOffset converts google.type.DateTime values to DATETIME, discarding the optional time offset. UseDateTimeWithoutOffset bool // UseOneofFields adds an extra STRING field for oneof fields with the name of the oneof, // containing the name of the field that is set. UseOneofFields bool // UseModeFromFieldBehavior sets the mode of a field to REQUIRED if the field is defined with REQUIRED behavior // in proto. UseModeFromFieldBehavior bool // UseProtoCommentsAsDescription use the proto comments to populate the description of the BigQuery field UseProtoCommentsAsDescription bool // UseJSONStructs use JSON type instead of string for STRUCT type UseJSONStructs bool }
SchemaOptions contains configuration options for BigQuery schema inference.
func (SchemaOptions) InferMessageSchema ¶ added in v0.18.0
func (o SchemaOptions) InferMessageSchema(msg protoreflect.MessageDescriptor) bigquery.Schema
InferMessageSchema infers the BigQuery schema for the given protoreflect.MessageDescriptor.
func (SchemaOptions) InferSchema ¶
func (o SchemaOptions) InferSchema(msg proto.Message) bigquery.Schema
InferSchema infers a BigQuery schema for the given proto.Message using options in MarshalOptions.
type UnmarshalOptions ¶
type UnmarshalOptions struct { // Schema contains the schema options. Schema SchemaOptions // If AllowPartial is set, input for messages that will result in missing // required fields will not return an error. AllowPartial bool // If DiscardUnknown is set, unknown fields are ignored. DiscardUnknown bool }
UnmarshalOptions is a configurable BigQuery format parser.
func (UnmarshalOptions) Load ¶
func (o UnmarshalOptions) Load(bqMessage []bigquery.Value, bqSchema bigquery.Schema, message proto.Message) error
Load the bigquery.Value list into the given proto.Message using the given bigquery.Schema using options in UnmarshalOptions object. It will clear the message first before setting the fields. If it returns an error, the given message may be partially set.
func (UnmarshalOptions) Unmarshal ¶
func (o UnmarshalOptions) Unmarshal(bqMessage map[string]bigquery.Value, message proto.Message) error
Unmarshal reads the given BigQuery row and populates the given proto.Message using options in UnmarshalOptions object. It will clear the message first before setting the fields. If it returns an error, the given message may be partially set.